viewport的前世与今生
以下仅为个人理解:
前言
不管是新手还是老手,在做移动端布局时页面头部都会引入这句话<mate name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no">,我刚入行时可能跟很多人一样认为这可能就是约定俗成的一句话,就如同其他代码导入一个包一样。随着移动端项目越做越多,逐渐发现"viewport"的水很深,不了解"viewport"的原理,很难把移动端的项目做好。
在吃"viewport"这道大餐之前,先坐下来品尝两道开胃小菜,先来说说像素的问题,没图说个x
什么是像素
什么是像素?貌似我们再熟悉不过了,某某手机摄像头达到1800万像素,某某屏幕的分辨率是1024*768像素等等,我们常定义width:200px,这是像素作为单位,px即像素的英文简写,像素(pixel),是指分辨率的尺寸单位,要说的当然是像素作为尺寸单位是怎么一个情况。
查阅网上资料,会发现关于像素单位的名词一大堆,逻辑像素、物理像素、渲染像素、设备像素、css像素。。。
实际上 逻辑像素=设备像素=显示屏或显示器的分辨率=这块屏是多大的多少寸
渲染像素=物理像素=css像素(苹果plus机型除外)
在苹果手机出现之前并没有这么多的名词,随着retina屏的出现x2,x3,事情变得复杂了。
这带来的问题就是1px != 1px,也就是我们在css里设置的1px宽或高,在屏幕上显示的并不一定就是1px宽或高。
设备像素是我们直观感觉到的像素,可以通过screen.width和screen.height获取到,宽度为1024px的普通屏幕,可以并排显示8个宽度为128px的元素,当页面缩放到200%时,只能显示4个,在缩放到200%的这个过程中,css像素宽并没有变化,而是一个css像素宽占用了两个设备像素,所以我们会主观感觉到256px的宽度。
苹果手机的retina屏幕就是用多个设备像素来渲染一个css像素的(如何做出实际表现为1px高度的下边框?)
width和device-width的关系,width指的就是元素宽度(以css像素衡量),device-width指的是设备的宽度(以分辨率的像素衡量),媒体查询大家都用过,那么@media screen and (max-width:320px)与@media screen and (max-device-width:320px)的区别大家能说得清楚吗?这个问题等说完viewport再来解答。
说完设备像素与css像素的关系,接下来进入正题。
什么是viewport?
翻译为视窗、视口,功能在于控制你网站的最高块状(block)容器:<html>
元素,它相当于是一个虚拟的框,因为看不见,所以难以理解。在桌面浏览器上,它就等于浏览器窗口的宽度高度,可通过document. documentElement. clientWidth/Height,在移动设备上有些复杂。我这里主要说个人理解的移动设备上的viewport。
移动设备的屏幕大小五花八门,所以带来了很多的问题。
研究者提出移动设备上有三个viewport,oh my god。。。
移动设备的先驱者可能是认为将来移动设备必将一统天下,所以移动设备上的浏览器都自认为必须能让所有的设备都正常显示,这种“自作聪明”的行为就来了下面的问题,没有做移动端适配的网站在移动设备上会这么显示。。。
不仅页面部分版式错乱了,而且左右侧边栏宽度太小,无法正常阅读。viewport太窄了容纳不了想要展示的内容,那么能不能让viewport变得宽一些?
320px的宽度是如何显示980px宽度的页面的呢。引出第一个viewport:visual viewport。
visual viewport是页面当前显示在屏幕上的部分。用户可以通过滚动来改变他所看到的页面的部分,或者通过缩放来改变visual viewport的大小。
如果把移动设备上浏览器的可视区域设为viewport的话,某些网站就会因为viewport太窄而显示错乱,所以这些浏览器就决定默认情况下把viewport设为一个较宽的值,比如980px,这样的话即使是那些为桌面设计的网站也能在移动浏览器上正常显示了.把这个浏览器默认的viewport叫做 layout viewport。这个layout viewport的宽度可以通过 document.documentElement.clientWidth 来获取。
把layout viewport想像成为一张不会变更大小或者形状的大图。现在想像你有一个小一些的框架,你通过它来看这张大图。(译者:可以理解为「管中窥豹」)这个 小框架的周围被不透明的材料所环绕,这掩盖了你所有的视线,只留这张大图的一部分给你。你通过这个框架所能看到的大图的部分就是visual viewport。当你保持框架(缩小)来看整个图片的时候,你可以不用管大图,或者你可以靠近一些(放大)只看局部。你也可以改变框架的方向,但是大图 (layout viewport)的大小和形状永远不会变。
Peter-paul Koch另外提出移动设备应当有一个理想状态的viewport,称为ideal viewport,它是通过width=device-width设置。
Viewport属性
在苹果的规范中,viewport是可以被设置的,它具有6个属性
其中最难理解的是缩放的属性,可以这样简单理解:
- 缩放是相对于ideal viewport来缩放的,缩放值越大,当前viewport的宽度就会越小
- 当前缩放值 = ideal viewport宽度 / visual viewport宽度。
那各属性综合起来会产生怎样的效果呢
<meta name="viewport" content="width=device-width"> //将viewpoert宽度设为理想宽度 <meta name="viewport" content="initial-scale=1"> //将viewpoert宽度设为理想宽度 <meta name="viewport" content="width=200, initial-scale=1"> //将viewpoert宽度设为理想宽度或者200px宽度中较大的那个
无论给layout viewpor设置的宽度是多少,而又没有指定初始的缩放值的话,那么iphone和ipad会自动计算initial-scale这个值,以保证当前layout viewport的宽度在缩放后就是浏览器可视区域的宽度,也就是说不会出现横向滚动条。比如说,在iphone上,我们不设置任何的viewport meta标签,此时layout viewport的宽度为980px,但我们可以看到浏览器并没有出现横向滚动条,浏览器默认的把页面缩小了。(编辑)