阅读(4190) (18)

CSS3媒体查询与自适应网页设计

2017-06-07 15:02:45 更新

前序

Media Query(媒体查询)是CSS3中的新增内容,用于定义不同媒体类型在不同CSS属性时的样式表现

在以前,如果我们想同一个网站对不同设备(比如PC端,手机端,平板端等等)提供支持,一般性的做法是针对不同的设备额外实现一套页面,在web端判断出访问设备类型时再路由到不同的实现。

这种做法的弊端很明显,因为额外的实现,所以后续的更新及维护都比较繁琐且成本越来越高。那么我们有没有一种方法,就是只有一份实现但是可以根据不同的设备自动做展现上的调整。Media Query为这种思路的实现提供了支持。

这里是一个例子,当改变浏览器窗口的大小时,页面上文本的颜色将会发生变化。其实现原理就是使用Media Query。

媒体类型(Media Type)

我们先来谈一谈媒体类型的相关内容。那么,何为媒体类型呢?

注意之前我们有说到,所谓媒体查询就是针对不同媒体类型在不同CSS属性时的样式表现。注意这句话,它有两个要素,第一是针对不同媒体类型,第二是针对CSS属性

具体点,我们来点代码,如下,


@media screen and (width: 888px) {
    p {
        color: gold;
    }
}

其中,

  • @media是关键字(可以将其理解成css的一种语法糖,跟@import类似)
  • screen,这个关键字就是我们所说的媒体类型(这里screen其实就是电脑屏幕)
  • width: 888px,需要查询的CSS属性

所以上面的CSS Media Query代码要表达的意思就是:当页面在电脑屏幕上展现时,且屏幕的width(宽度)属性为888px时,设置所有的p标签元素的字体颜色为gold(土豪金,哈哈~)。

除了上面提到的screen,常见有媒体类型如下表,

媒体类型 备注 是否常用
all 匹配所有设备
braille 盲文设备
embossed 盲文打印
handheld 手持设备
print 打印模式
projection 演示模式、幻灯片等
screen 电脑屏幕
speech 演讲
tty 固定字母间距的网格的媒体,比如电传打字机
tv 电视媒体

看到上面关于媒体类型的表格后,其实我们常用的也就allprintscreen这几种类型。其中screen要属于最常用的媒体类型了。

在具体使用media type时,我们还可以使用not或者only这两个关键字修饰媒体类型,比如


@media only screen and (width: 888px) {
    /* your css code */
}

或者


@media not print and (width: 888px) {
    /* your css code */
}

其中,前者(only修饰词)表示@media设置的样式只对screen类型适用;后者(not修饰词)表示@media设置的样式对除了print类型之外的所有设备类型生效。

媒体查询(Media Query)

说完了媒体类型,我们再来说一说媒体查询。其一般的语法如下,


@media screen and (width: 888px) {
    /* your css code */
}

媒体查询中查询两字的含义就体现在screenwidth: 888px上(可能更加倾向后者)。换句话说,screenwidth: 888px其实都是查询的条件,当有多个条件时,我们使用and将他们连起来。

上面的示例代码中,查询页面的width属性,当其宽度为888px时,将应用特别设置的样式。

不过Media Query所支持的CSS属性是有限的,与一般的CSS属性并不一致,而且会有一些特别的可选项。如下表,

可查询属性 属性值类型 是否可用Max/Min前缀 描述 常用
color 整数 定义每一组输出设备的彩色原件个数。如果不是彩色设备,则等于0
color-index 整数 定义在输出设备的彩色查询表中的条目数。如果没有使用彩色查询表,则等于0
width 长度 定义输出设备中的页面可见区域宽度
height 长度 定义输出设备中的页面可见区域高度
device-width 长度 定义输出设备的屏幕可见宽度(设备本身的宽度)
device-height 长度 定义输出设备的屏幕可见高度(设备本身的高度)
orientation portrait/landscape 定义height是否大于或等于width。值portrait代表是(竖屏),landscape代表否(横屏
aspect-ratio 整数/整数 定义widthheight的比率(宽高比
device-aspect-ratio 整数/整数 定义device-widthdevice-height的比率(宽高比)。如常见的显示器比率:4/3, 16/9, 16/10
monochrome 整数 定义在一个单色框架缓冲区中每像素包含的单色原件个数。如果不是单色设备,则等于0
scan progressive/interlaced 定义电视类设备的扫描工序
grid 整数 用来查询输出设备是否使用栅格或点阵。只有10才是有效值,1代表是,0代表否
resolution dpi/dpcm 定义设备的分辨率。如:96dpi, 300dpi, 118dpcm

看过上面的表格之后,我们会发现其实Media Query就是为了不同设备而诞生的。就目前而言,我们常用的查询属性也就那么几个,大部分与宽高有关系(其实就是设置的展现区域大小)。

从上面的表格中,我们可以看出有部分的可查询属性还有添加max-或者min-前缀进行修饰。比如,


@media screen and (min-width: 961px) and (max-width: 1200px) {
    p {
        color: pink;
    }
}

上面代码的含义是指,当展现页面的宽度大于960px且小于1200px时,将p标签的字体颜色设置为粉色。

这个例子中,我们使用了widthheight这两个可查询属性,而且还使用了maxmin对齐进行修饰,分别表示最小宽度最大宽度

自适应(响应式)网页设计

Responsive Web Design,国人将其翻译成响应式Web设计,个人觉得翻译成自适应Web设计可能更佳。它的意思就是可以自动识别屏幕宽度、并做出相应调整的网页设计

我们可以使用CSS3的Media Query做一些自适应的网页设计。比如,


<head>
    <link rel="stylesheet" media="screen and (max-width: 480px)" href="tiny.css" />
    <link rel="stylesheet" media="screen and (min-width: 481px) and (max-width: 600px)" href="small.css" />
    <link rel="stylesheet" media="screen and (min-width: 601px) and (max-width: 960px)" href="middle.css" />
    <link rel="stylesheet" media="screen and (min-width: 961px)" href="pc.css" />
</head>

上述代码的含义很明确,查询屏幕的宽度属性,根据不同的宽度加载不同的css文件。

有时候我们为了减少css文件的解析,将所有的媒体查询代码写在同一个css文件中,在html中仅作一次加载。如下,


<head>
    <link rel="stylesheet" href="style.css" />
</head>


@media screen and (max-width: 480px) {
    /* your css code */
}
@media screen and (min-width: 481px) and (max-width: 600px) {
    /* your css code */
}
/* more css code */

这两种做法的效果是一致的。

下面是一些示例网站,可以访问它们,然后改变浏览器的大小观察其展示的变化。

  1. Hicksdesign,不同的屏幕大小将导致页面的侧栏发生变化。
  2. A List Apart,不同的屏幕大小将导致页面导航栏和图片行数发生变化。
  3. Colly,不同的屏幕大小将导致页面图片的分列不同。

自适应布局的局限性

这里额外说一点,所谓的自适应布局远远没有这么简单,并不是靠着在不同屏幕大小上对页面布局做一些调整就可以了。

它还将面临下面的几个问题,

  • 不同屏幕尺寸下,图片(视频)等资源的展示如何处理
  • 在较小的屏幕尺寸下,往往需要对一些元素进行隐藏,这势必会造成流量(带宽资源)的浪费
  • 即使一套页面可以自适应好几种设备了,此时一旦有更新,需要同时维护各个设备相关的css代码并且要做好协调

兼容性

  • IE8(及其以下都不支持)
  • IE9+
  • Chrome 5+
  • Opera 10+
  • Firefox 3.6+
  • Safari 4+

关于Media Query浏览器的兼容性,除了IE8及其以下的浏览器不支持,其他的主流浏览器基本上都支持(这里不考虑Firefox、Safari、Opera这些浏览器的低版本了)。要是实在要想在IE8上使用媒体查询,需要用到引入额外的js插件css3-medieaqueries.js

参考列表