移动端的视口viewport涉及三个视口:
- 布局视口(Layout Viewport)
- 视觉视口(Visual Viewport)
- 理想视口(Ideal Viewport)
布局视口(Layout Viewport):
- 移动设备上的浏览器认为自己必须能让所有的网站都正常显示,即使那些不是为移动设备设计的网站(为PC端设计的网站)。
- 由于移动设备的屏幕比PC的宽小很多,如果以浏览器的可视区域作为viewport, 则那些为PC端设计的网站放到移动设备上显示时,必然会因为移动设备的viewport太窄,而挤作一团,甚至布局什么的都会乱掉。
- 因此一般浏览器会默认把viewport设为一个较宽的值, 比如980px, 所以 PC 上的网页基本能在手机上呈现,只不过元素看上去比PC端小一半(PC端一般1920px),可以通过手动缩放网页。
- 这个浏览器默认的viewport叫做 layout viewport。这个layout viewport的宽度可以通过 document.documentElement.clientWidth 来获取。
- 布局视口使视口与移动端浏览器屏幕宽度完全独立开。CSS 布局将会根据它来进行计算,并被它约束。
视觉视口(Visual Viewport):
- 视觉视口是用户当前看到的区域,即移动设备屏幕宽度内可以看到的css像素个数。
- 用户可以通过缩放操作视觉视口,同时不会影响布局视口。
- 视觉视口和缩放比例的关系为:
当前缩放值 = 理想视口(Ideal Viewport)宽度 / 视觉视口(Visual Viewport)宽度
移动设备的理想视口宽度是固定不变的,因此当用户放大(缩放值变大)时,CSS 像素将跨越更多的物理像素, 不变的屏幕宽度内看到的css像素个数会减少, 视觉视口将会变小。
理想视口(Ideal Viewport):
- 因为现在越来越多的网站都会为移动设备进行单独的设计,所以必须还要有一个能完美适配移动设备的viewport。
- 所谓的完美适配指,首先不需要用户缩放和横向滚动条就能正常的查看网站的所有内容;
- 第二,显示的文字的大小是合适,比如一段14px大小的文字,不会因为在一个高密度像素的屏幕里显示得太小而无法看清,理想的情况是这段14px的文字无论是在何种密度屏幕,何种分辨率下,显示出来的大小都是差不多的。
- 当然,不只是文字,其他元素像图片什么的也是这个道理。
- 这个viewport叫做 ideal viewport, ideal viewport的宽度等于移动设备的屏幕宽度。
- ideal viewport 并没有一个固定的尺寸,不同的设备拥有有不同的 ideal viewport。
- 所有的 iphone 的 ideal viewport 宽度都是 320px,无论它的屏幕宽度是 320 还是 640,也就是说,在 iphone 中,css 中的 320px 就代表 iphone 屏幕的宽度。
- 但是安卓设备就比较复杂了,有320px的,有360px的,有384px的等等,关于不同的设备ideal viewport的宽度都为多少,可以到 http://viewportsizes.com 去查看一下,里面收集了众多设备的理想宽度。
- ideal viewport 的意义在于,无论在何种分辨率的屏幕下,那些针对ideal viewport 而设计的网站,不需要用户手动缩放,也不需要出现横向滚动条,都可以完美的呈现给用户。
把当前的viewport宽度设置为 ideal viewport 的宽度:
方法一:
<meta name="viewport" content="width=device-width">
要得到ideal viewport就必须把默认的layout viewport的宽度设为移动设备的屏幕宽度。因为meta viewport中的width能控制layout viewport的宽度,所以我们只需要把width设为width-device这个特殊的值就行了。
通过width=device-width,所有浏览器都能把当前的viewport宽度变成ideal viewport的宽度,但要注意的是,在iphone和ipad上,无论是竖屏还是横屏,宽度都是竖屏时ideal viewport的宽度。
方法二:
<meta name="viewport" content="initial-scale=1">
这句代码也能达到和前一句代码一样的效果,也可以把当前的的viewport变为 ideal viewport。
因为这里的缩放值是1,也就是没缩放,但却达到了 ideal viewport 的效果,所以,那答案就只有一个了,缩放是相对于 ideal viewport来进行缩放的,当对ideal viewport进行100%的缩放,也就是缩放值为1的时候,不就得到了 ideal viewport吗?
通过 initial-scale=1 也能把当前的viewport宽度变成 ideal viewport 的宽度,但这次轮到了windows phone 上的IE 无论是竖屏还是横屏都把宽度设为竖屏时ideal viewport的宽度。
总结:
- 要把当前的viewport宽度设为ideal viewport的宽度,既可以设置 width=device-width,也可以设置 initial-scale=1,但这两者各有一个小缺陷,就是iphone、ipad以及IE 会横竖屏不分,通通以竖屏的ideal viewport宽度为准。
- 所以,最完美的写法应该是,两者都写上去,这样就 initial-scale=1 解决了 iphone、ipad的毛病,width=device-width则解决了IE的毛病:
<meta name="viewport" content="width=device-width, initial-scale=1">
width 和 initial-scale=1 同时出现,并且还出现了冲突?比如:
<meta name="viewport" content="width=400, initial-scale=1">
1. 当遇到这种情况时,浏览器会取它们两个中较大的那个值。
2. 例如,当width=400,ideal viewport的宽度为320时,取的是400;
3. 当width=400, ideal viewport的宽度为480时,取的是ideal viewport的宽度。
4.(ps:在uc9浏览器中,当initial-scale=1时,无论width属性的值为多少,此时viewport的宽度永远都是ideal viewport的宽度)
initial-scale的默认值:
- 当不写initial-scale这个属性时, 默认值很显然不会是1。
- 安卓手机initial-scale默认值好像没有方法能够得到,或者就是干脆它就没有默认值。
- 根据测试,我们可以在iphone和ipad上得到一个结论,就是无论你给layout viewpor设置的宽度是多少,而又没有指定初始的缩放值的话,那么iphone和ipad会自动计算initial-scale这个值,以保证当前layout viewport的宽度在缩放后就是浏览器可视区域的宽度,也就是说不会出现横向滚动条。
- 比如说,在iphone上,我们不设置任何的viewport meta标签,此时layout viewport的宽度为980px,但我们可以看到浏览器并没有出现横向滚动条,浏览器默认的把页面缩小了。
- 根据上面的公式,当前缩放值 = 理想视口(Ideal Viewport)宽度 / 视觉视口(Visual Viewport)宽度,我们可以得出:当前缩放值 = 320 / 980, 即当前的initial-scale默认值应该是 0.33。
- 结论:在iphone和ipad上,无论你给viewport设的宽的是多少,如果没有指定默认的缩放值,则iphone和ipad会自动计算这个缩放值,以达到当前页面不会出现横向滚动条(或者说viewport的宽度就是屏幕的宽度)的目的。