iLeo
  • 1.2k

如何做好移动端的响应式设计:Viewport控制

新人翻译,欢迎转载~
英文原文地址:http://bitsofco.de/2015/respove-design-viewport/
原文例程地址:https://github.com/ireade/viewports
(可下载例程参照阅读)

当我们在做响应式设计时,关注最多的是CSS的@media查询。不可否认,@media查询完成了很多工作,但一个网站的响应能力还是取决于对Viewport的控制。当我们想根据屏幕尺寸来自动变化页面布局时,我们会像这样做:

@media screen and (min-width: 960px) {
  body { background-color: green; }
}

@media screen and (max-width: 960px) and (min-width: 500px) {
  body { background-color: pink; }
}

@media screen and (max-width: 500px) {
  body { background-color: yellow; }
}

在浏览器上调整窗口大小,可以看到网页的响应能力是乎没有任何问题的。

页面缩放

那么问题来了

在移动端浏览页面时就出现异常了。

没有进行Viewport控制的iPhone6
(没有进行Viewport控制的iPhone6上的显示效果)

页面虽然可以看到,但不能自适应手机的屏幕。之所以会有这样的问题,是设备尺寸和Viewport尺寸不一致导致的。为了更好的理解这两个尺寸之间的不同点,下面就简单说说:

  • 设备像素:这个是物理层面的像素数量,比如一台iPhone6,是375x667像素。(注:这里所说的设备像素有两种类型,硬件像素和设备独立像素,不过这个区别与此文无关);
  • CSS像素:这个是我们在CSS使用过程中的一个抽象的单位,它并没有一个绝对的尺寸,页面上单个CSS像素的大小完全取决于Viewport的大小;
  • Viewport:Viewport决定了页面的像素密度。比如一个宽750px的Viewport,表示屏幕上横向排布了750个CSS像素(Viewport在未缩放的情况下)。

Viewport是"无关设备"的,它不知道也不关心我们的设备到底有多大的屏幕。

大多数显示器的Viewport尺寸默认在800px到1024px之间,这就解释了为什么之前我们的例程可以在电脑上正常显示而不用管当前屏幕的尺寸。

通过meta标签来控制Viewport

可以设置meta标签中的viewport信息,以解决Viewport尺寸不匹配的问题。meta标签的用法如下:

<meta  name="viewport" content="key=value, key=value">

标签内容中有6个关键字:

  • width
  • height
  • initial-scale
  • minimum-scale
  • maximum-scale
  • user-scalable

WIDTH

可以用width来设置viewport的宽度,以替代那些不合适的默认宽度。我们可以给其设定一个固定大小,但设定成device-width更加明智一些,这样我们可以兼容不同大小的屏幕。

<meta name="viewport" content="width=device-width">

加了这句话之后,我们的例程看起来就正常多了。

width=device-width
(在iPhone6上设置width=device-width之后的显示效果)

INITIAL-SCALE

在移动设备上,用户有时会需要缩放页面,当页面缩放时,Viewport的像素尺寸也会相应的改变,但CSS尺寸不会变。

比如,在一个400px宽的Viewport中有一个元素,设定width: 100px;,这时该元素就横跨了1/4的屏幕。如果用户把页面放大到两倍大小,这时Viewport宽度变成了200px,但元素仍然宽100个CSS像素。这时这个元素就占了半个屏幕了。

我们可以通过initial-scale来设置CSS像素和Viewport像素之间的比例,通常情况下是1:1。这个参数的设置可以很好的解决width=device-width设置所带来的问题。有些移动设备浏览器会在纵向模式时默认使用设备宽度,当切换到横向模式时页面显示就会不正常。

没有设置initial-scale
(在没有设置initial-scale的横向iPhone6上的显示效果)

如图所示,当iPhone处于横向模式时,我们看到的还是宽度小余500px时的页面状态。不过不要慌张,我们可以通过设置initial-scale为1来解决这个问题。

<meta name="viewport" content="width=device-width, initial-scale=1">

设置了initial-scale
(在设置了initial-scale的横向iPhone6上的显示效果)

USER-SCALABLE,MAXIMUM-SCALE以及MINIMUM-SCALE

这几个参数用来控制页面的缩放能力。

  • Maximum-scale:这个是用户可以缩放页面的最大比例。比如说设置为1,用户就无法缩放页面。假如设置为2,用户就可以把页面放大到1个CSS像素等于2个Viewport像素的大小;
  • Minimum-scale:这个是用户可以缩放页面的最小比例。假如设置为2,页面的最小比例就是原比例的两倍,并且无法缩小到原始比例;
  • User-scalable:如果设置了user-scalable=no,用户将无法对页面进行缩放。

由于这几个参数限制了用户对页面的操作,通常不建议使用它们。

用CSS来控制Viewport

虽然现在很多人都在用viewport,但其实viewport并不是HTML5标准中的正式成员。W3C目前正在研究将viewport@viewport规则的形式加入到CSS当中,@viewport规则与viewport标签有异曲同工之妙,只是将用于布局的viewport归还给CSS,现在已经有部分开发者在尝试@viewport了。

@viewport {
  zoom: 1.0; /* same as initial-scale=1 */
  width: device-width;
}

/* Vendor specific prefixes */
@-ms-viewport 
@-webkit-viewport 
@-moz-viewport 
@-o-viewport

@viewport正式发布之前,还是先继续使用viewport标签吧,如果有兴趣的话可以尝试一下测试版的@viewport

总结

为了保证你的响应式页面能够在移动端正常运行,把下面这句话加到你的<head>元素里面吧~

<meta name="viewport" content="width=device-width, initial-scale=1">
阅读 11.4k

推荐阅读
iLeox Notes
用户专栏

真正的优秀,是比昨天的自己更优秀。

9 人关注
8 篇文章
专栏主页