viewport是什么?
一般来说,在移动浏览器上页面渲染是在一个叫viewport的页面绘制区域内。
手机浏览器把页面放在一个虚拟的“窗口”(viewport)中,通常这个虚拟的“窗口”(viewport)比屏幕宽,这样就不用把每个网页挤到很小的窗口中(这样会破坏没有针对手机浏览器优化的网页的布局),用户可以通过平移和缩放来看网页的不同部分。
- layout viewport:是网页的所有内容,他可以全部或者部分展示给用户。
- visual viewport:是当前显示给用户内容的窗口,你可以拖动或者放大缩小网页。
viewport和屏幕的真实尺寸并不是对应的,如在Safari Mobile中viewport默认宽度(320px)是屏幕真实尺寸(640px)的一半,这里不管是用window.innerHeight还是window.screen.width拿到的都是320px。
当然我们可以通过meta设置改变viewport的比例,如initial-scale=.5就可以让viewport和屏幕一致的尺寸,这个比例在不同的手机上并不一定是2倍关系,特别是Android手机。而且改变viewport比例后可能会导致后续制作中出现一系列问题。另外Android系统中可以在viewport设置target-densitydpi=device-dpi让viewport的尺寸和屏幕真实尺寸保持一致,但iOS不起作用,所以这个方法不具有普遍性。不要纠结一定要拿到屏幕真实尺寸,就把viewport的尺寸当成屏幕的尺寸进行页面设计和制作肯定是没有问题的。
例如:当你打开一个960px设计的网页时,手机会根据css中的百分比进行缩放。比如总长960的页面,导航条是20%。(实际解析出来就是192px)但是你不可能每个属性都是百分比吧,比如文字大小。那么我用320px屏幕打开,导航条就成了64px了,但是我的字体大小是12px啊,完了,本来能显示很多汉字的(192/12)现在只能显示64/12个汉字了。
Apple找到了一个办法:在移动版(iOS)的Safari中定义了viewport meta标签①,它的作用就是创建一个虚拟的窗口(viewport),而且这个虚拟窗口的分辨率接近于桌面显示器,Apple将其定位为980px②。
①除此之外不同移动浏览器厂商也有不同的解决方案,例如UCweb就是使用中间件技术。
②不同的浏览器厂商对于layout viewport的大小定义不同
Safari iPhone: 980px Opera: 850px Android WebKit: 800px IE: 974px
一、基本概念
首先,viewport指视口,浏览器上(或一个app中的webview)显示网页的区域。PC端的视口是浏览器窗口区域,而移动端的则存在三个不同的视口:
layout viewport:布局视口
visual viewport:视觉视口
ideal viewport:理想视口
1. layout viewport 布局视口
在PC端的网页的layout viewport即浏览器页面显示的整个区域,也可以理解成网页的绘制区域。而在移动端由于其屏幕较小,无法全部显示PC端页面的全部内容,所以默认情况下(不用<meta name="viewport">去控制),移动端会指定一个大于其浏览器显示区域layout viewport,一般是980px,如下图所示:
图1
在chrome浏览器上的实验结果,未进行视口控制的页面的默认宽度为980px,即页面在宽度为980px的页面上进行了绘制。
2. visual viewport 视觉视口
visual viewport,顾名思义指浏览器可视区域,即我们在移动端设备上看到的区域。为了区别其和layout viewport的区别,我们看一下下面的图:
layout viewport:
visual viewport:
网页的实际绘制区域视口大小layout viewport比我们在手机上可以看到的大小要大,所以我们手机端视觉视口会出现横向滚动条。
3. ideal viewport 理想视口
所谓理想视口,即页面绘制区域可以完美适配设备宽度的视口大小,不需要出现滚动条即可正常查看网站的所有内容,且文字图片清晰,如所有iphone的理想视口宽度都为320px,安卓设备的理想视口有320px、360px等等。
二、视口的控制
如何进行视口的控制以进行移动端页面适配呢?
我们自然想到,在移动端开发时都会在开头加上这样一行内容用于移动端页面的适配:
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no">
1
这行代码即用来控制viewport,其中的参数有以下几个:
参数 含义
width 设置layout viewport的宽度,为一个正整数,或字符串"width-device"
initial-scale 设置页面的初始缩放值,为一个数字,可以带小数
minimum-scale 允许用户的最小缩放值,为一个数字,可以带小数
maximum-scale 允许用户的最大缩放值,为一个数字,可以带小数
height 设置layout viewport 的高度,这个属性对我们并不重要,很少使用
user-scalable 是否允许用户进行缩放,值为"no"或"yes", no 代表不允许,yes代表允许
下面重点谈一下width和initial-scale
1. width
width用来设置layout viewport的宽度,即页面具体绘制区域的宽度,在不使用<meta>进行控制视口时,以iphone为例,其会设置视口宽度为980px。
另外width可设置为width-device字符串,表示设置视口宽度为设备的ideal viewport,如在iphone上为320px。
2. initial-scale
指页面初始的缩放值,其值可以通过如下公式进行计算:
initial-scale = ideal viewport / visual viewport
1
如initial-scale值为2,ideal viewport值为320px,则visual viewport即为160px,如下图所示,我们设置viewport为:
<meta name="viewport" content="width=device-width,initial-scale=2.0,user-scalable=no">
1
由于visual viewport小于layout viewport,横向出现滚动条,通过下方375px的div可以看出,visual viewport正好为ideal viewport的一半
关于initial scale的默认值
关于initial scale,在没有使用<meta>标签时,它的值并不为1,以iphone为例,如图1中的情况
当我们没有使用<meta>标签时,其layout viewport为980px,但同时我们的可视区域即visual viewport也为980px,正好完全显示了所有的内容,可以通过公式计算此时的initial scale为:
ideal viewport / visual viewport = 320 / 980 = 0.33
1
所以当没有设置时,iniatal scale并不为1
另外,经过对iphone和ipad等ios设备的测试,不管width设置为多宽,设备都会自动计算你的initial scale值,以使得整个屏幕正好可以容纳整个页面不出现滚动条。如下所示: