提到响应式设计时,首先会想到媒体查询(media query)来通过窗口大小应用不用的样式设置。 然而这些媒体查询正常工作的前提是正确的视口(viewport)设置。先给出正确的方法:

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

在移动设备的浏览器在渲染页面时,为了避免未经过响应式设计的页面显示不正常, 默认情况下会使用一个较大的『虚拟视口』,然而这使得经过响应式设计的页面也会被错误地缩放。

典型的 viewport 设置

viewport属性由Apple首先发明,用来更好地识别经过响应式优化的网站。该属性尚未标准化。

设置 width

在没有任何viewport设置的情况下,375px宽度的IPhone 6中渲染,虚拟视口宽度为980px:

no viewport

这时添加下列的视口宽度设置:

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

渲染视口宽度就变成正确的375px了:

no viewport

设置 initial-scale

此外,在iPhone下的Safari中,横屏(landscape)时默认会对页面进行缩放,字体突然变大。 见https://css-tricks.com/probably-use-initial-scale1/。设置initial-scale后可解决此问题:

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

所有 viewport 属性

width属性控制视口的宽度,可以设为像width=600这样确切的像素数, 也可以设为device-width这样的特殊值。相应地,还有heightdevice-height属性, 在需要根据视口高度调整元素大小/位置时有用。

另外,控制缩放级别的除了initial-scale属性外,还有maximum-scaleminimum-scaleuser-scalable等属性来控制允许用户以怎样的方式放大或缩小页面。完整的属性列表如下:

属性 描述
width 设备虚拟视口的宽度
device-width 设备屏幕的物理宽度
height 设备虚拟视口的高度
device-height 设备屏幕的物理高度
initial-scale 访问页面的初始缩放,1.0 表示无缩放
minimum-scale 访客可对页面的最小缩放级别,1.0 表示无缩放
maximum-scale 访客可对页面的最大缩放级别,1.0 表示无缩放
user-scalable 是否允许进行缩放,值为yesno

兼容IE10 Snap模式

高版本的Windows支持经典模式和Metro模式。IE10可以方便地Snap到屏幕的一边, 这样可以很好地同时使用两个窗口。 在IE10的Snap模式下,400px以下的视口中<meta content="viewport">标签会失效, 见https://timkadlec.com/2012/10/ie10-snap-mode-and-responsive-design/

既然<meta content="viewport">标签失效了,我们需要在CSS中设置视口:

@-ms-viewport{
  width: device-width;
}

相关的响应式设计建议

在浏览页面时,用户习惯纵向而不是横向滚动页面, 通过viewport设置和媒体查询确保不发生横向滚动。

  1. 不要使用大宽度的绝对定位元素。例如较宽的图片(<img>)或代码(<pre>)默认就会超出宽度。
  2. 页面布局不要依赖与特定宽度的视口。不同设备视口的CSS宽度非常不同,确保同时兼容小屏幕和大屏幕。
  3. 使用媒体查询来适配不同大小的屏幕。避免直接给元素设置较大的宽度,尝试用相对宽度来代替。

本文采用 知识共享署名 4.0 国际许可协议(CC-BY 4.0)进行许可,转载注明来源即可: https://harttle.land/2016/04/21/viewport.html。如有疏漏、谬误、侵权请通过评论或 邮件 指出。