在CSS中,有一个极其实用的功能:@media 响应式布局。具体来说,就是可以根据客户端的介质和屏幕大小,提供不同的样式表或者只展示样式表中的一部分。通过响应式布局,可以达到只使用单一文件提供多平台的兼容性,省去了诸如浏览器判断之类的代码。
当然这种设计也存在着缺点,比如我所见的不少使用响应式布局的设计在适配移动端时大量使用 display:none 隐藏富媒体元素,这样势必会导致大量不必要的流量。因此,如果有较为重要的移动端需求,那么还是开发专门的移动版页面为好。不过,对于诸如内容较少的页面或者单页式网站来说,响应式布局依然不失为一种偷懒的好方法 ^ ^
一、在 <head> 链接CSS文件时提供判断语句,选择性加载不同的CSS文件
<link rel="stylesheet" href="middle.css" media="screen and (min-width: 400px)">
这句意味在满足 media 的判断语句 screen and (min-width: 400px) 即 屏幕并且最小宽度不小于400px 的介质上面使用 middle.css 。
二、在CSS文件中分段书写不同设备的代码
/* CSS Code */ @media screen and (min-width: 600px) { /* CSS Code */ } @media screen and (max-width: 599px) { /* CSS Code */ }
相信这个代码也很容易理解,写在 @media 语句段外的是共用代码,第一个 @media 语句段是 屏幕以及最小宽度600px ,第而个 @media 语句段是 屏幕以及最大宽度599px 。
如果不同的代码段有冲突或者重叠,会按照CSS原本的代码优先级排序,即后方代码替代前方代码,等等。
三、媒体介质类型
CSS3中提供了多种媒体介质类型,虽然常用的就俩……注意媒体类型名称区分大小写,并且尽管有些介质类型有重合,但是一个平台只会有一种介质类型。(我猜这个标准很多浏览器不会遵守吧?)
- all – 全部媒体类型
- braille – 盲文触摸装置
- embossed – 分页盲文打印机 (W3C的无障碍做的真细心……)
- handheld – 小屏幕和流量有限的手持设备(注意!安装标准来说移动设备都应该使用这个介质类型,但是实际上安卓根本不理会这个介质,请使用 screen 结合媒体查询语句使用)
- print – 提供给打印机的样式,最常用的介质类型,打印页面时获得适合阅读的效果
- projection – 投影,给投影机使用(有人用?)
- screen – 彩色屏幕,最常用的介质类型,一般和屏幕大小表达式联合使用
- speech – 语音朗诵,用于屏幕阅读软件(和将来的Siri?)
- tty – 固定间距字符网格,例如功能机那样的
- tv – 智能电视设备(唔不知道我家的创维酷开支持如何……)
四、媒体查询语句
除了媒体介质,我们还能通过 and 使用 Media Query 语句,达到对屏幕大小的判断生成响应式布局。(可以通过改变浏览器窗口大小在桌面下测试效果)
一个 Media Query 包含一种媒体类型,如果媒体类型没有指定,那么就是默认类型all,比如:
media="(max-width: 600px)"
也可以使用 and 表示同时满足这两者时生效,达到限定范围:
handheld and (min-width:20em) and (max-width:50em)
逗号 , 被用来表示 并列 和 或者 :
handheld and (max-width:20em), screen and (max-width:30em)
not 用来排除符合表达式的设备:
not screen and (color)
下面来解释一下遇到冲突时的机制:
<link rel="stylesheet" href="styleA.css" media="screen and (min-width: 800px)"> <link rel="stylesheet" href="styleB.css" media="screen and (min-width: 600px) and (max-width: 800px)"> <link rel="stylesheet" href="styleC.css" media="screen and (max-width: 600px)">
上面将设备分成3种,分别是宽度大于800px时,应用 styleA ,宽度在600px到800px之间时应用 styleB ,以及宽度小于600px时应用 styleC 。那假如宽度正好等于800px时该应用那个样式?是 styleB,因为前两条表达式都成立,按CSS默认优先级规则后者覆盖了前者。
因此,为了避免冲突,这个例子正常情况应该这样写:
<link rel="stylesheet" href="styleA.css" media="screen"> <link rel="stylesheet" href="styleB.css" media="screen and (max-width: 800px)"> <link rel="stylesheet" href="styleC.css" media="screen and (max-width: 600px)">
五、浏览器支持
媒体介质在CSS2中已经被添加,因此主流平台的浏览器毫无疑问都可以正确支持。但是 Media Query 语句是CSS3中添加的新功能,部分浏览器可能并不理解。例如IE能成功解读媒体介质,但是却无法解读 and 后面的媒体查询语句,就会连带媒体介质一起忽略。为了让不识别媒体查询语句的浏览器依然识别到媒体介质,可以使用 only 关键字进行hack。
<link rel="stylesheet" href="example.css" media="only screen and (color)">
添加了 only 关键字后,支持媒体查询语句的浏览器依然正常解析。但不支持媒体查询语句但正确读取媒体介质的设备,由于先读取到 only 而不是 screen ,将忽略这个样式。不支持媒体查询的IE不论是否有 only ,都直接忽略样式。
最后是浏览器支持情况:
IE8-- IE9+
- Chrome 5+
- Opera 10+
- Firefox 3.6+<
Safari 4+
媒体类型还支持 not和only关键字,它们可以用来更方便的定位某个媒体设备:
not:排除某种制定的媒体类型
@media not print and (color){ }
only:指定某种特定的媒体类型,可以用来排除不支持媒体查询的浏览器:
@media only screen and (color){ }