2.2 为什么响应式设计需要媒体查询
没有CSS3的媒体查询模块,就不能针对设备特性(如视口宽度)设置特定的CSS样式。如果你仔细研读W3C关于CSS3媒体查询模块的规范,就会看到媒体查询的官方解释:
HTML 4和CSS 2目前支持为不同的媒体类型设定专有的样式表。比如,一个页面在屏幕上显示时使用无衬线字体,而在打印时则使用衬线字体。screen和print是两种已定义的媒体类型。媒体查询让样式表有更强的针对性,扩展了媒体类型的功能。
媒体查询由媒体类型和一个或多个检测媒体特性的条件表达式组成。媒体查询中可用于检测的媒体特性有width、height和color(等)。使用媒体查询,可以在不改变页面内容的情况下,为特定的一些输出设备定制显示效果。
2.2.1 媒体查询语法
CSS媒体查询到底长什么样,更重要的是,它是怎么起作用的?
将下面这段代码插入到任意某个CSS文件的最后,然后预览与之关联的网页:
在现代浏览器(如果是IE,至少要IE9)中浏览该网页并不断调整浏览器窗口宽度。页面的背景颜色就会根据当前的视口尺寸而发生变化。为了清晰起见,我在这里使用了颜色名称,但实际上最好使用十六进制颜色值,如#ffffff。
接下来,让我们继续分析媒体查询,学习如何对其进行充分利用。
如果经常使用CSS 2样式表,你就知道可以通过<link>标签的media属性为样式表指定设备类型(如显示屏或打印机)。具体说来,就是在HTML页面的<head>标签中插入一个如下面代码片段所示的link标签:
媒体查询则能使我们根据设备的各种功能特性来设定相应的样式,而不仅仅只针对设备类型。可以将媒体查询想象成对浏览器的提问。如果浏览器回答“是”,则应用样式;如果回答是“否”,则不应用样式。相对于在CSS 2中能且只能问浏览器“你是一块显示屏吗?”,媒体查询能问的问题要多一点。例如,媒体查询可以问:“你是一块纵向放置的显示屏吗?”我们看看对应的实际代码:
首先,媒体查询表达式询问了媒体类型(你是一块显示屏吗?),然后询问了媒体特性(显示屏是纵向放置的吗?)。任何纵向放置的显示屏设备都会加载portrait-screen.css样式表,其他设备则会忽略该文件。在媒体查询的开头追加not则会颠倒该查询的逻辑。例如,下面的代码就会颠倒前例中的效果,会使非纵向放置的显示屏设备加载样式文件:
也可以将多个表达式组合在一起。如,我们扩展一下前面的例子,限制只有视口宽度大于800像素的显示屏设备才能加载文件。
更进一步,还可以写一个媒体查询列表。查询列表中的任意一个查询为真,则加载文件。全部查询都不为真,则不加载。例子如下:
这里有两点需要注意。第一,媒体查询之间使用逗号分隔。第二,你会注意到在projection之后,没有and,也没有任何特性/值的组合。没有后续表达式,意味着只要是projection就满足条件。本例中,样式会应用于所有的投影仪。
和以前编写CSS规则一样,基于媒体查询也可以按条件加载样式。在上面的例子中,我们在向页面的<head></head>标签中链接CSS文件时使用了媒体查询。除此之外,我们还可以在CSS样式表中使用媒体查询。例如,将下面的代码插入样式表,在屏幕宽度小于等于400像素的设备上,h1元素的文字颜色就会变成绿色。
还可以使用CSS的@import指令在当前样式表中按条件引入其他样式表。例如下面的代码会给视口最大宽度为360像素的显示屏设备加载一个名为phone.css的样式表。
切记,使用CSS的@import方式会增加HTTP请求(这会影响加载速度),所以请谨慎使用该方法。
2.2.2 媒体查询能检测那些特性
创建媒体查询时,最常用的是设备的视口宽度(width)和屏幕宽度(device-width)。依我的经验,很少需要检测其他特性。但是,为方便查阅,下面列出了所有可供媒体查询检测的特性,希望其中有能让你心动的特性。
width:视口宽度。
height:视口高度。
device-width:渲染表面的宽度(对我们来说,就是设备屏幕的宽度)。
device-height:渲染表面的高度(对我们来说,就是设备屏幕的高度)。
orientation:检查设备处于横向还是纵向。
aspect-ratio:基于视口宽度和高度的宽高比。一个16∶9比例的显示屏可以这样定义aspect-ratio: 16/9。
device-aspect-ratio:和aspect-ratio类似,基于设备渲染平面宽度和高度的宽高比。
color:每种颜色的位数。例如min-color: 16会检测设备是否拥有16位颜色。
color-index:设备的颜色索引表中的颜色数。值必须是非负整数。
monochrome:检测单色帧缓冲区中每像素所使用的位数。值必须是非负整数,如monochrome: 2。
resolution:用来检测屏幕或打印机的分辨率,如min-resolution: 300dpi。还可以接受每厘米像素点数的度量值,如min-resolution: 118dpcm。
scan:电视机的扫描方式,值可设为progressive(逐行扫描)或interlace(隔行扫描)。如720p HD电视(720p的p即表明是逐行扫描)匹配scan: progressive,而1080i HD 电视(1080i中的i表明是隔行扫描)匹配scan: interlace。
grid:用来检测输出设备是网格设备还是位图设备。
在上述所有特性中,除scan和grid之外,都可使用min和max前缀来创建一个查询范围。例如,分析如下所示的代码片段:
这里对width应用了min和max来设定查询范围。这样phone.css文件只会引入视口宽度介于200像素至360像素的显示屏设备。
2.2.3 用媒体查询改造我们的设计
毫无疑问,你肯定知道CSS代表层叠样式表。所谓层叠,就是指样式表中后面的样式会覆盖前面相同的样式(除非前面的样式具有更高的针对性)。因此我们可以在样式表的开头设置基本样式,以便适应所有设计,然后使用媒体查询来进一步重写相应的部分。例如,先针对大视口设计(用户大多数情况下使用鼠标),将导航链接设计成简单的文字链接;然后再针对较小的视口,使用媒体查询重写这部分样式,为拇指一族提供更大的点击区域。
2.2.4 加载媒体查询的最佳方法
现代浏览器虽然可以智能地忽略与自身不匹配的样式文件,但它却不一定不下载这些文件。因此,将不同媒体查询的样式保存到独立的文件中没有太大好处(个人喜好或为便于组织代码除外)。使用多个独立的文件会增加用于页面渲染的HTTP请求数量,从而导致页面加载变慢。
Respond.js(https://github.com/scottjehl/Respond)是为Internet Explorer 8及更低版本增加媒体查询支持的最快的JavaScript工具,但它目前无法解析CSS的@import命令。因此,建议在已有的样式表中追加媒体查询样式。使用如下语法即可在已有样式表中加入媒体查询:
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论