如何理解移动端的viewport?
viewport指的是可以看到web内容的区域。
在PC端中,视口的宽度和浏览器窗口的宽度时保持一致的。
在移动端中,由于屏幕的尺寸较小,导致对于视口的定义也比较复杂。在移动端中,视口分为:布局视口,视觉视口和理想视口。
物理像素和CSS像素
像素是屏幕中显示颜色的最小区域。屏幕中的像素越多,能看到的内容也就越多,或者说当设备尺寸相同时,像素越密集,画面就越精细。
物理像素(device pixels)
指的是设备屏幕的物理像素,任何设备的物理像素都是固定的。
CSS像素(CSS pixels)
CSS像素是一个抽象的概念,它与物理像素之间的关系并不是一对一的关系。它们之间的比例会受到很多因素的影响,如屏幕的分辨率,用户是否缩放等。
早期的设备中,分辨率比较低,iphone3的分辨率是320X480,那个时候一个css像素确实等于一个物理像素。但是iphone4的时候屏幕的分辨率变成了640X960,而且屏幕的尺寸是没有变化的,这就意味着物理像素的个数变成了原来的4倍,所以这时一个CSS像素就为2两个物理像素。
如果用户对页面进行了放大,那就意味着屏幕中展示的CSS像素减少,所以一个CSS像素所占有的物理像素就会变大。
三种视口(viewport)
由于移动设备的宽度通常在240-960px之间,而大多数web端的网页宽度最少也是800px。所以如果按照web浏览器的方式,将浏览器的窗口宽度当做视口宽度的话,会使网页在移动端展示的时候出现排版混乱的情况(将web浏览器窗口缩小到手机大小就知道了)。
在这种情况下,移动端浏览器引入了布局视口、视觉视口和理想视口的概念,以另一种方式来定义视口,将视口宽度和浏览器宽度分隔开来。
1.布局视口(layout viewport)
移动端浏览器厂商为了使web中内容完整显示在浏览器中,定义了一个虚拟的布局视口,一般是800px或者980px(css像素)。所以PC端中网页的内容基本可以显示在浏览器中,只是看上去很小,像是缩小了若干倍,但是可以通过放大来查看。

布局视口的宽度可以通过 document.documentElement.clientWidth 来获取
html中提供了viewport元数据用来设置布局视口的宽度。
<meta name="viewport" content="width=200px">
viewport meta的属性
- width —— 布局视口的宽度(可以为device-width或者是数值)
- height —— 布局视口的高度(一般不需要设置)
- initial-scale —— 设置页面的初始缩放比例,布局视口 = 理想视口 / initial-scale
- maximum-scale —— 设置最大的缩放比例(0.1,10]
- minimum-scale —— 设置最小的缩放比例(0.1,10]
- user-scalable —— 是否允许用户手动缩放(yes/no)
布局视口的特点
- CSS中的百分比是以布局视口的宽度为基准来算的
- initial-scale也是用来描述视口宽度的,布局视口 = 理想视口 / initial-scale
- 在没有设置viewport meta的时候,移动端浏览器默认会显示整个布局视口,所以看上去会很小
2.视觉视口(visual viewport)
视觉视口指的是当前用户看到的区域,用户可以放大或缩小视觉视口,但是不会影响布局视口。

视觉视口、理想视口和缩放比例之间的关系:
scale = ideal viewport / visual viewport
注意:这里需要区分initial-scale与scale的区别。initial-scale影响的是布局视口,而scale影响的是视觉视口。说明布局视口只能初始化的时候设定
所以当放大的时候,视觉视口的将会变小,CSS像素与物理像素之间的比例也会越来越大。
3.理想视口(ideal viewport)
默认的布局视口并不是理想的宽度,因为它会导致页面的内容会非常小,很难与页面之间进行交互。所以浏览器厂商引入了理想视口的概念。
理想视口的特点
- 不需要用户缩放和横向滚动条就能正常的查看网站的所有内容
- 显示的文字的大小是合适,比如一段14px大小的文字,不会因为在一个高密度像素的屏幕里显示得太小而无法看清,理想的情况是这段14px的文字无论是在何种密度屏幕,何种分辨率下,显示出来的大小都是差不多的
理想视口对应的像素并不是物理像素或者CSS像素,而是一种叫设备逻辑像素的px,简称dip。dip与设备的物理像素无关,一个dip在任意像素密度的屏幕上都占据着相同大小的空间。当布局视口和理想视口相同的时候,相同的元素在不同的分辨率显示在大小是一样的,即占据的逻辑像素应该是一样的。在这种情况下,1个dip等于1个CSS像素,可以理解为1dip的物理长度就是在这种情况下1px(css)的物理长度
理想视口的尺寸是各浏览器厂商针对不同的屏幕尺寸定义的,所以不同的浏览器理想的宽度可能不同。
viewport meta中的scale属性都是基于理想视口的尺寸进行缩放的。
将布局视口宽度与理想视口宽度设置一致的方法
// 方案一,早期设备中旋转之后布局视口没有变化
<meta name="viewport" content="width=device-width" >
// 方案二,IE10不兼容
<meta name="viewport" content="initial-scale=1" >
// 最完美方案
<meta name="viewport" content="width=device-width,initial-scale=1" >
总结一些需要注意的点
- viewport只对移动端有作用,PC无效
- initial-scale影响的是布局视口的宽度,scale影响的是视觉视口的宽度。两者都是基于理想视口的宽度计算的
- 理想视口是宽度是由浏览器厂商定义的,在理想视口的情况下,页面元素展示的尺寸是合适交互的。但是并不意味着,只要将布局视口设置成理想视口的大小,页面元素就能自适应布局展示。如果想要页面自适应布局展示,需要额外写响应式的代码。也就是说,仅仅将布局视口宽度设置成理想视口的宽度,布局仍然可能是很混乱的,但是元素的展示尺寸是合适的。写响应式布局代码时,需要参考这一点
