谈谈响应式

上一篇说到,响应式是跨终端的其中一种实现方式。那到底,响应式具体的定义是什么?

什么是响应式

响应式网页设计(RWD,Responsive Web Design)这个术语由 Ethan Marcott 提出,它是弹性网格布局、弹性图片、媒体和媒体查询三种开发技巧的整合。

一切的手段都服务于目的,为了实现跨终端,响应式并不一定是最佳选择。在预算充足的情况下,根据终端检测跳转到不同的模板,这样就能基于用户的设备、位置、连接速度,以及包括技术特性在内的其他因素为其提供不同的内容、设计和交互,大大提升用户体验。

然而,并不是所有项目都有这样的先决条件。在大多数情况下,根据不同设备不同视口大小提供与之匹配还是优先选择。走得更远一点, 2014 年定稿的 HTML5 为我们提供了更多且更加语义化的标签, CSS3 的媒体查询更是响应式设计不可或缺的组成部分。

而在移动端上网人数数量越来越庞大的现在,「移动优先」也成为了现在优先的设计理念。也就是先考虑移动端的设计,再细化到 PC 端,并遵从「内容优先」的理念。

下面介绍一下使用响应式的一些基本技巧。

Viewport

在实现响应式设计时,第一步我们会在 HTML 文件的 <head> 标签里面插入一个 <meta> 标签:

1
<meta content = "initial-scale = 1, maximum-scale = 1, user-scalable = no, width = device-width" name = "viewport" />

它的意思是,页面 CSS 计算时使用的宽度根据设备给定值自适应、初始不缩放、不允许用户缩放、最大缩放因子为 1 。作用是,阻止移动浏览器自动调整页面大小。

Viewport 最初只是 iOS Safari 的私有属性,但现在 CSS 的 @viewport 声明也已经可以使用。而现在最流行的 viewport meta 标签中基本的属性定义有:

  • width:控制 Viewport 大小,单位 px,可以指定一个数值或常量 “device-width” ;iOS Safari 上默认值为 980,取值范围为 200 ~ 10000 。
  • height:和 width 相对应,常量为 “device-height” ;iOS Safari 上取值范围为 233 ~ 10000 。
  • initial-scale:初始缩放比例。
  • maximum-scale:允许用户缩放的最大比例。
  • minimun-scale: 允许用户缩放的最小比例。
  • user-scalable:用户是否可以手动缩放。

媒体查询

设置完 viewport meta 标签后,任何浏览器都不能缩放页面了,现在我们可以针对不同视口修正设计效果,使用媒体查询针对设备特性设置特定的 CSS 样式。媒体查询由媒体类型和一个或多个检测媒体特性的条件表达式组成,这些用户检测的媒体特性包括:

  • width:视口宽度。
  • height:视口高度。
  • device-width:渲染表面(设备屏幕)的宽度。
  • device-height:渲染表面(设备屏幕)的高度。
  • orientation:检查设备处于横向还是纵向。
  • aspect-ratio:基于视口宽度和高度的宽高比。该值包含代表了水平像素数 / 垂直像素数的比例。
  • device-aspect-ratio:和 aspect-ratio 类似,描述了描述设备渲染平面宽度和高度的宽高比。
  • color:指定输出设备每个像素单元的比特值。如果设备不支持输出颜色,则该值为 0 。
  • color-index:设备的颜色索引表中的颜色数,值必须是非负整数。
  • monochrome:指定单色帧缓冲区中每个像素的比特数。如果不是黑白设备,值为 0 。
  • resolution:用来检测屏幕或打印机的分辨率,用每英寸(dpi)或每厘米(dpcm)像素点数的度量值来表示。
  • scan:电视机的扫描方式,值为 progressive (逐行扫描)和 interlace (隔行扫描)两种。
  • grid:用来检测输入设备是网格设备还是位图设备。

以上列出那么多,但其实最常用的也就 width 和 device-width,其它的只是一并列出方便查阅。另外,在上述除 scan 和 grid 外的特性,都可用 min 和 max 前缀来创建查询范围。

这里是一个简单的媒体查询例子:

1
2
3
@media screen and (min-width: 320px) and (max-width: 768px) {
//这里是最小宽度为 320px,最大宽度为 768px 的设备的 CSS 样式
}

为了遵循结构、表现和行为分离,我们会在样式表的开头设置基本样式,以便适应所有设计,然后在底部使用媒体查询来进一步重写相应部分。因为 CSS 后面的样式会覆盖前面的样式,除非前面的样式具有更高的针对性。

另外,将不同媒体查询的样式保存在独立文件中并无太大好处。我们可以利用 gulp 这种前端构建工具对 js 文件和 css 文件进行压缩,以减少 HTTP 请求数量,从而导致网页加载变慢注1

Response.js 是为 IE 8 及更低版本增加媒体查询支持的最快的 Js 工具,但它目前无法解析 CSS 的 @import 命令注2

百分比布局

  1. 将网页从固定布局修改为百分比布局,创造流动的弹性界面。《无懈可击的 Web 设计》一书中有一个简易可行的百分比宽度公式:

    目标元素宽度 / 上下文元素宽度 = 百分比宽度
    
  2. 用 em 或者 rem 代替 px:

    我们都知道,根元素默认的 font-size 是 16px 。引用一下师弟的知乎回答

    em 是根据父元素字体大小定义的,父元素字体大小是多少 px,该子元素的 1em 就等于多少 px,所以用 em
    很不方便的地方就是随时都要考虑父元素的字体大小,为了弥补这个缺点便出现了 rem 。
    rem 跟 em 不同的地方在于 rem 是根据根元素(html)的字体大小来确定的。

  3. 弹性图片

    在现代浏览器(IE 7+)中想要实现图片随流动布局缩放非常简单,只需:

    1
    2
    3
    img {
    max-width: 100%;
    }

注 1:HTTP 能减少网页加载时间的原因是,请求耗时比较长,而且请求虽然可以并发,但是也有限制,一般都是 6 个。

注 2:@import 引用的 CSS 会等到页面被加载完再加载,因此在页面 DOM 加载完成到 CSS 导入完成中间可能会有一段时间页面上的内容没有样式,这是导致 FOUC (无样式内容闪烁)的罪魁祸首。