CSS利用@media和viewport实现响应式布局自动适配手机电脑等
了解@Media相关:
1、了解Media Queries
Media Queries能在不同的条件下使用不同的样式,使页面在不同在终端设备下达到不同的渲染效果。其原理就是允许添加表达式用以媒体查询(包括媒体类型和媒体特性),以此来选择不同的样式表,从而自动适应不同的屏幕分辨率。
css2里面虽然支持@media属性,但是能实现的功能比较少,一般只用做打印的时候做特殊定义的CSS,我们不去讨论。
css3的@media属性在CSS3里面已经演变成一种 media queries(媒体查询/匹配)了,在CSS3里面,可以用查询语句来匹配各种类型的屏幕。
2、了解@media 和 @media screen的区别
@media screen的css在打印设备里是无效的,而@media在打印设备里是有效的,如果css需要用在打印设备里,那么就用@media ,否则,就用@media screen。不过这只是笼统的做法,其实如果把“screen”换为“print”,写为@media print,那么该css就可用到打印设备上了,但要注意,@media print声明的css只能在打印设备上有效。
3、了解CSS中的width、device-width、resolution、aspect-ratio
width/height :定义输出设备中的 页面可见区域宽度/高度。
device-width/height :定义输出设备的屏幕可见宽/高度。
resolution :定义设备的分辨率。如:96dpi, 300dpi, 118dpcm
aspect-ratio :定义输出设备中的页面可见区域宽度与高度的比率。
4、了解media样式的使用方法
4.1、一种方法是直接在link中判断设备的尺寸,然后引用不同的css文件:
<link rel=”stylesheet” media=”mediatype and|not|only (media feature)” href=”mystylesheet.css”>
demo如下:当前屏幕的宽度大于等于400px时应用 styleA.css样式文件。。
<link rel=”stylesheet” type=”text/css” href=”styleA.css” media=”screen and (min-width: 400px)”>
4.2、另一种方法是直接写在 style 标签里:
@media mediatype and|not|only (media feature) {
CSS-Code;
}
demo如下:screen 是媒体类型里的一种,CSS2.1定义了多种媒体类型
<style>
@media screen and (max-width: 600px) { /*当屏幕尺寸小于600px时,应用下面的CSS样式*/
.class {
background: #ccc;
}
}
</style>
上述格式是中使用“@media”开头,然后指定媒体类型(理解为设备类型),随后是指定媒体特性(理解为屏幕尺寸),其中还包括关键字and 、 not(排除某种设备)、only(限定某种设备)
@media后带的参数详解
多媒体类型 mediatype
值 描述
all 用于所有多媒体类型设备
print 用于打印机
screen 用于电脑屏幕,平板,智能手机等。
speech 用于屏幕阅读器
多媒体特性 media feature
媒体特性是通过min来表示大于等于或max表示小于做为逻辑判断,
值 描述
aspect-ratio 定义输出设备中的页面可见区域宽度与高度的比率
color 定义输出设备每一组彩色原件的个数。如果不是彩色设备,则值等于0
color-index 定义在输出设备的彩色查询表中的条目数。如果没有使用彩色查询表,则值等于0
device-aspect-ratio 定义输出设备的屏幕可见宽度与高度的比率。
device-height 定义输出设备的屏幕可见高度。
device-width 定义输出设备的屏幕可见宽度。
grid 用来查询输出设备是否使用栅格或点阵。
height 定义输出设备中的页面可见区域高度。
max-aspect-ratio 定义输出设备的屏幕可见宽度与高度的最大比率。
max-color 定义输出设备每一组彩色原件的最大个数。
max-color-index 定义在输出设备的彩色查询表中的最大条目数。
max-device-aspect-ratio 定义输出设备的屏幕可见宽度与高度的最大比率。
max-device-height 定义输出设备的屏幕可见的最大高度。
max-device-width 定义输出设备的屏幕最大可见宽度。
max-height 定义输出设备中的页面最大可见区域高度。
max-monochrome 定义在一个单色框架缓冲区中每像素包含的最大单色原件个数。
max-resolution 定义设备的最大分辨率。
max-width 定义输出设备中的页面最大可见区域宽度。
min-aspect-ratio 定义输出设备中的页面可见区域宽度与高度的最小比率。
min-color 定义输出设备每一组彩色原件的最小个数。
min-color-index 定义在输出设备的彩色查询表中的最小条目数。
min-device-aspect-ratio 定义输出设备的屏幕可见宽度与高度的最小比率。
min-device-width 定义输出设备的屏幕最小可见宽度。
min-device-height 定义输出设备的屏幕的最小可见高度。
min-height 定义输出设备中的页面最小可见区域高度。
min-monochrome 定义在一个单色框架缓冲区中每像素包含的最小单色原件个数
min-resolution 定义设备的最小分辨率。
min-width 定义输出设备中的页面最小可见区域宽度。
monochrome 定义在一个单色框架缓冲区中每像素包含的单色原件个数。如果不是单色设备,则值等于0
orientation 定义输出设备中的页面可见区域高度是否大于或等于宽度。(检测设备目前处于横向还是纵向状态。)
resolution 定义设备的分辨率。如:96dpi, 300dpi, 118dpcm
scan 定义电视类设备的扫描工序。
width 定义输出设备中的页面可见区域宽度。
and / not / only / all
not: not是用来排除掉某些特定的设备的,比如 @media not print(非打印设备)。
only: 用来定某种特别的媒体类型。
对于支持 Media Queries 的移动设备来说,如果存在 only 关键字,移动设备的 Web 浏览器会忽略 only关键字并直接根据后面的表达式应用样式文件。
对于不支持 Media Queries 的设备但能够读取 Media Type 类型的 Web浏览器,遇到 only 关键字时会忽略这个样式文件。only用来指定某种特定的媒体类型,可以用来排除不支持媒体查询的浏览器。
all: 所有设备,这个应该经常看到。在Media Query中如果没有明确指定Media Type,那么其默认为all
@media使用例子
demo1:可以使用关键词”and”将多个媒体特性结合在一起。也就是说,一个Media Query中可以包含0到多个表达式,表达式又可以包含0到多个关键字,以及一种媒体类型。当屏幕在600px~900px之间时,body的背景色渲染为“#f5f5f5”,如下所示。
@media screen and (min-width:600px) and (max-width:900px){
body {background-color:#f5f5f5;}
}
demo2:可以使用多条语句来将同一个样式应用于不同的媒体类型和媒体特性中。style.css样式被用在宽度小于或等于480px的手持设备上,或者被用于屏幕宽度大于或等于960px的设备上,如下所示
<linkrel=”stylesheet” type=”text/css” href=”style.css” media=”handheld and (max-width:480px), screen and (min-width:960px)” />
上面代码中style.css样式被用在宽度小于或等于480px的手持设备上,或者被用于屏幕宽度大于或等于960px的设备上。也
demo3:注意因为<style>标签中后面的样式会覆盖前面的样式,所以要注意不能顺序错误,如下会导致不能实现根据不同尺寸查询渲染,如下所示
@media (min-width: 992px){ //>=992的设备 }
@media (min-width: 768px){ //>=768的设备 }
demo4:实现横屏和竖屏的媒体查询
/* 竖屏 */
@media screen and (orientation: portrait) and (max-width: 720px) { 对应样式 }
/* 横屏 */
@media screen and (orientation: landscape) { 对应样式 }
@media实践
到目前为止,CSS3 Media Queries得到了众多浏览器支持,除了IE6-8浏览器不支持之外,在所有现代浏览器中都可以完美支持。还有一个与众不同的是,Media Queries在其他浏览器中不要像其他CSS3属性一样在不同的浏览器中添加前缀。
1、兼容低版本IE浏览器的响应式布局开发
步骤1、兼容移动设备展示效果,需要在 <head> 之中添加 viewport 元数据标签。
其中width = device-width表示显示宽度等于当前设备的宽度,initial-scale初始的缩放比例(默认设置为1.0),maximum-scale允许用户缩放到的最大比例(默认设置为1.0) , user-scalable禁止用户手动缩放页面(默认设置为no);
<meta name=”viewport” content=”width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no”>
<meta name=”HandheldFriendly” content=”true”>
步骤2、加载兼容性文件
因为IE8既不支持HTML5也不支持CSS3 Media,所以我们需要加载两个JS文件,来保证我们的代码实现兼容效果;其中Respond.js 为 IE6-8 以及其它不支持 CSS3 Media Queries 的浏览器提供媒体查询的 min-width 和 max-width 特性,实现响应式网页设计(Responsive Web Design)。html5shiv.js使ie9以下浏览器能识别html5新增标签。
<!–[if lt IE 9]>
<script src=”https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js“></script>
<script src=”https://oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js“></script>
<![endif]–>
为提供跨浏览器的高度一致性,我们还可以加载Normalize.css,已被用于Twitter Bootstrap,HTML5 Boilerplate,GOV.UK,Rdio,CSS Tricks以及许许多多其他的框架,工具和网站上。normalize.css下载
步骤3、设置IE渲染方式默认为最高(这部分可以选择添加也可以不添加)
现在有很多人的IE浏览器都升级到IE9以上了,所以这个时候就有又很多诡异的事情发生了,例如现在是IE9的浏览器,但是浏览器的文档模式却设置是IE8。为了防止这种情况,我们需要下面这段代码来让IE的文档模式永远都是最新的:
<meta http-equiv=”X-UA-Compatible” content=”IE=edge”>
(如果想指定使用IE版本,可写成:<meta http-equiv=”X-UA-Compatible” content=”IE=EmulateIE9″>)
一个更给力的写法:
<meta http-equiv=”X-UA-Compatible” content=”IE=Edge,chrome=1″>
怎么这段代码后面加了一个chrome=1,这个Google Chrome Frame(谷歌内嵌浏览器框架GCF),如果有的用户电脑里面装了这个chrome的插件,就可以让电脑里面的IE不管是哪个版本的都可以使用Webkit引擎及V8引擎进行排版及运算,无比给力,不过如果用户没装这个插件,那这段代码就会让IE以最高的文档模式展现效果。这段代码我还是建议你们用上,不过不用也是可以的。
步骤4、响应式布局开发(媒体查询来设置不同样式、使用响应式字体rem单位、图片自适应处理)
在创建响应式布局的时候习惯先写非响应式布局,页面固定宽度大小,我觉得这个对在座的各位没有任何难度。如果完成了非响应式那么我在去添加媒体查询(Media Query)和响应式代码。这种操作更容易实现响应式特性。
// 媒体查询来设置不同样式
应用于超大屏显示器下的样式,加入一个终端的分辨率大于1920px,这里的样式将覆盖之前所定义的样式
@media screen and (min-width:1920px){
#head { }
#content { }
#footer { }
}
// 图片拉伸自适应使用max-width
#wrap img{
max-width:100%;
height:auto;
}
上述代码中ID为wrap内的图片会根据wrap的宽度改变已达到等宽扩充,height为auto的设置是为了保证图片原始的高宽比例,以至于图片不会失真。
// 背景图片拉伸自适应使用CSS3的background-size
#log a{display:block;
width:100%;
height:40px;
text-indent:55rem;
background-img:url(logo.png);
background-repeat:no-repeat;
background-size:100% 100%;
}
background-size是css3的新属性,用于设置背景图片的大小,有两个可选值,
第一个值用于指定背景图的width,第2个值用于指定背景图的height,如果只指定一个值,那么另一个值默认为auto。
background-size:cover; 等比扩展图片来填满元素
background-size:contain; 等比缩小图片来适应元素的尺寸
2、前端bootstrap响应式框架
bootstrap栅格系统详解:https://v3.bootcss.com/css/#grid
bootstrap栅格系统简介
Bootstrap 提供了一套响应式、移动设备优先的流式栅格系统,随着屏幕或视口(viewport)尺寸的增加,系统会自动分为最多12列。它包含了易于使用的预定义类,还有强大的minxin 用于生成更具语义的布局。栅格系统用于通过一系列的行(row)与列(column)的组合来创建页面布局,你的内容就可以放入这些创建好的布局中。下面就介绍一下 Bootstrap 栅格系统的工作原理:
“行(row)”必须包含在 .container (固定宽度)或 .container-fluid (100% 宽度)中,以便为其赋予合适的排列(aligment)和内补(padding)。
通过“行(row)”在水平方向创建一组“列(column)”。
你的内容应当放置于“列(column)”内,并且,只有“列(column)”可以作为行(row)”的直接子元素。
类似 .row 和 .col-xs-4 这种预定义的类,可以用来快速创建栅格布局。Bootstrap 源码中定义的 mixin 也可以用来创建语义化的布局。
通过为“列(column)”设置 padding 属性,从而创建列与列之间的间隔(gutter)。通过为 .row 元素设置负值 margin 从而抵消掉为 .container 元素设置的 padding,也就间接为“行(row)”所包含的“列(column)”抵消掉了padding。
负值的 margin就是下面的示例为什么是向外突出的原因。在栅格列中的内容排成一行。
栅格系统中的列是通过指定1到12的值来表示其跨越的范围。例如,三个等宽的列可以使用三个 .col-xs-4 来创建。
如果一“行(row)”中包含了的“列(column)”大于 12,多余的“列(column)”所在的元素将被作为一个整体另起一行排列。
栅格类适用于与屏幕宽度大于或等于分界点大小的设备 , 并且针对小屏幕设备覆盖栅格类。 因此,在元素上应用任何 .col-md-*栅格类适用于与屏幕宽度大于或等于分界点大小的设备 , 并且针对小屏幕设备覆盖栅格类。 因此,在元素上应用任何 .col-lg-*不存在, 也影响大屏幕设备。
在栅格系统中,我们在 Less 文件中使用以下媒体查询(media query)来创建关键的分界点阈值。
/* 超小屏幕(手机,小于 768px) */
/* 没有任何媒体查询相关的代码,因为这在 Bootstrap 中是默认的(还记得 Bootstrap 是移动设备优先的吗?) */
/* 小屏幕(平板,大于等于 768px) */
@media (min-width: @screen-sm-min) { … }
/* 中等屏幕(桌面显示器,大于等于 992px) */
@media (min-width: @screen-md-min) { … }
/* 大屏幕(大桌面显示器,大于等于 1200px) */
@media (min-width: @screen-lg-min) { … }
可以看到在其栅格布局中不同的类前缀代表的是不同屏幕尺寸下的应用
超小屏幕 手机 (<768px) 小屏幕 平板 (≥768px) 中等屏幕 桌面显示器 (≥992px) 大屏幕 大桌面显示器 (≥1200px)
栅格系统行为 总是水平排列 开始是堆叠在一起的,当大于这些阈值时将变为水平排列C
.container 最大宽度 None (自动) 750px 970px 1170px
类前缀 .col-xs- .col-sm- .col-md- .col-lg-
扩展知识:
1、单位pixel-ratio/dpi/dppx区别?
dpi 属性: 每英寸包含点的数量(dots per inch)
dppx 属性: 每像素包含点的数量(dots per pixel)。
dpcm 属性: 每厘米包含点的数量(dots per centimeter)
注意:
普通屏幕通常包含96dpi,一般将2倍于此的屏幕称之为高分屏,即大于等于192dpi的屏幕,比如Mac视网膜屏就达到了192dpi(即2dppx),打印时一般会需要更大的dpi;
1dppx = 96dpi
1dpi ≈ 0.39dpcm
1dpcm ≈ 2.54dpi
1in = 2.54cm = 25.4 mm = 101.6q = 72pt = 6pc = 96px
PS: 图片在iphone中模糊的原因
iphone 的物理分辨率是 320X480,但是呈现的内容却是 640×960,但其实我们设置的 css px 是相对于物理分辨率的,即 320×480,但是因为我们设置的 css px 要显示在更宽阔的 640×960 的内容区域里头,所以10个 css px 在 640×960 的呈现效果就相当于5个 device px 在 320×480 的呈现效果。
所以如果图片得大小是100×100,那么到iphone里头就会被放大2倍,于是图像会变得比以前模糊,通常得解决办法是,用 background-size 设置为50%,以前的一半,然后再在 iphone 放大2倍,等于没变化,恢复到正常效果,不模糊了。
2、PC端按屏幕尺寸整理
分辨率 比例 | 设备尺寸
1024*500 (8.9寸)
1024*768 (比例4:3 | 10.4寸、12.1寸、14.1寸、15寸; )
1280*800(16:10 |15.4寸)
1280*1024(比例:5:4 | 14.1寸、15.0寸)
1280*854(比例:15:10 | 15.2)
1366*768 (比例:16:9 | 不常见)
1440*900 (16:10 17寸 仅苹果用)
1440*1050(比例:5:4 | 14.1寸、15.0寸)
1600*1024(14:9 不常见)
1600*1200 (4:3 | 15、16.1)
1680*1050(16:10 | 15.4寸、20.0寸)
1920*1200 (23寸)
通过上面的电脑屏蔽及尺寸的例表上我们得到了几个宽度
1024 1280 1366 1440 1680 1920
CSS代码
@media (min-width: 1024px){
body{font-size: 18px}
} /*>=1024的设备*/
@media (min-width: 1100px) {
body{font-size: 20px}
} /*>=1024的设备*/
@media (min-width: 1280px) {
body{font-size: 22px;}
}
@media (min-width: 1366px) {
body{font-size: 24px;}
}
@media (min-width: 1440px) {
body{font-size: 25px !important;}
}
@media (min-width: 1680px) {
body{font-size: 28px;}
}
@media (min-width: 1920px) {
body{font-size: 33px;}
}
3、 CSS中相对长度值代表另一类值,包括:REM、 EM和 vw/vh。
相对长度值的优势非常明显,可以用它们来构建响应式网站。即网站会根据你的设定,有规律地自适应屏幕大小。
EM的大小定义:
在处理font-size属性时,与父元素的字体大小有关,1em=父元素的字体大小px;
在处理其他一些属性,如height时,与元素自身的字体大小有关,1em=本元素的字体大小px。
vw 代表窗口宽度的1%。 也就是说如果你把width设置为10vw,元素就会占窗口10%的宽度。
vh 代表窗口高度的1%。 也就是说如果你把height设置为10vh,元素就会占窗口10%的高度。
REM的大小定义:
css3引入了新的单位叫做rem, 和em类似但它是相对于html元素,rem更方便使用。rem是相对于根元素的,不要忘记重置根元素字体大小(浏览器默认字体大小为16px):
1rem=根元素字体大小px。
html{font-size:625%;} 即字体大小为625%*16px=100px=1rem
完成后,你可以定义响应式字体:
@media (min-width:640px) { body{ font-size:0.12rem; }} 即字体大小为12px
@media (min-width:960px) { body{ font-size:0.14rem;width:1.4rem; }} 即字体大小为14px,宽度为140px
@media (min-width:1200px) { body{ font-size:0.16rem; }}
4、viewport
移动设备默认的viewport是layout viewport,也就是那个比屏幕要宽的viewport,但在进行移动设备网站的开发时,我们需要的是ideal viewport。那么怎么才能得到ideal viewport呢?这就该轮到meta标签出场了。
我们在开发移动设备的网站时,最常见的的一个动作就是把下面这个东西复制到我们的head标签中:
<metaname=”viewport”content=”width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0″>
该meta标签的作用是让当前viewport的宽度等于设备的宽度,同时不允许用户手动缩放。也许允不允许用户缩放不同的网站有不同的要求,但让viewport的宽度等于设备的宽度,这个应该是大家都想要的效果,如果你不这样的设定的话,那就会使用那个比屏幕宽的默认viewport,也就是说会出现横向滚动条。
这个name为viewport的meta标签到底有哪些东西呢,又都有什么作用呢?
meta viewport 标签首先是由苹果公司在其safari浏览器中引入的,目的就是解决移动设备的viewport问题。后来安卓以及各大浏览器厂商也都纷纷效仿,引入对meta viewport的支持,事实也证明这个东西还是非常有用的。
在苹果的规范中,meta viewport 有6个属性(暂且把content中的那些东西称为一个个属性和值),如下:
width | 设置layout viewport 的宽度,为一个正整数,或字符串”width-device” |
initial-scale | 设置页面的初始缩放值,为一个数字,可以带小数 |
minimum-scale | 允许用户的最小缩放值,为一个数字,可以带小数 |
maximum-scale | 允许用户的最大缩放值,为一个数字,可以带小数 |
height | 设置layout viewport 的高度,这个属性对我们并不重要,很少使用 |
user-scalable | 是否允许用户进行缩放,值为”no”或”yes”, no 代表不允许,yes代表允许 |
这些属性可以同时使用,也可以单独使用或混合使用,多个属性同时使用时用逗号隔开就行了。
此外,在安卓中还支持 target-densitydpi 这个私有属性,它表示目标设备的密度等级,作用是决定css中的1px代表多少物理像素
target-densitydpi | 值可以为一个数值或 high-dpi 、 medium-dpi、 low-dpi、 device-dpi 这几个字符串中的一个 |
特别说明的是,当 target-densitydpi=device-dpi 时, css中的1px会等于物理像素中的1px。
因为这个属性只有安卓支持,并且安卓已经决定要废弃 target-densitydpi 这个属性了,所以这个属性我们要避免进行使用 。