关于移动端(一)viewport

近段时间做了一个web app的demo,涉及到了一些在移动端开发时遇到的东西,所以来梳理下,这里主要是关于viewport的东西,

近段时间做了一个web app的demo,涉及到了一些在移动端开发时遇到的东西,所以来梳理下,这里主要是关于viewport的东西,其实在之前实习的过程中也遇到过,现在回想起来,其实原来的一些理解还是有点问题的,首先先附上原来的一些整理理解

##关于像素##

###1. css像素(CSS pixels)###
字面意思就是在css中使用的像素,这个也很好理解,一般的从视觉拿过来的图,都是以一个一定的宽度的psd的图,这里的像素跟视觉图里的像素个人理解是一样的,这个最终将会是web端中的实物像素

###2. 设备像素###
显示屏幕的的最小物理单位

###3. 缩放比###
之所以这些概念在pc端的web中没有很大的关系的原因是,在pc端,初始的页面下,两者的缩放比是1:1,也就是说两者是相等的概念,当然现在chrome浏览器可以按住ctrl键,实现页面的缩放,从而改变缩放比,你就会看到元素被放大或者被缩小,在这一过程中,你需要注意的一点就是有多少像素在适配屏幕

当你放大的时候,会有更少的css像素在设备的屏幕中,图会变得更加模糊,一个css像素,也许会覆盖多个设备像素,这个效果图可以看参考引文中的一些图;反之缩小的情况

###4. 其他几个相关的衡量指标###

(1) 每英寸所拥有的像素(PPI / DPI):物理尺寸跟设备像素比,数值越高,即代表显示屏能够以越高的密度显示图像

PPI = 对角线上的像素数 / 对角线的英寸长度

(2) 设备独立像素(dips):这个貌似不怎么好解释,可以看看wikipedia

a physical unit of measurement based on a co-ordinate system held by a computer
and represents an abstraction of a pixel for use by an application that an 
underlying system then converts to physical pixels

不同设备有不同的显示效果,这个和设备硬件有关,一般我们为了支持WVGA、HVGA和QVGA 推荐使用这个,不依赖像素.在wikipedia上对这个概念的解释是一组基于计算机坐标系的物理单位,它代表了一个抽象的像素用来给应用来使用,同时会由计算机系统再将其转化为具体的物理像素.它的一个典型的应用就是允许了移动设备软件进行缩放显示信息以及在不同大小屏幕上进行用户交互.这个抽象单位允许一个应用可以用像素作为一个衡量单位,同时设备的图形系统会将这个抽象的单位转化为一个适合该设备的实际像素衡量单位.(设备独立像素到物理像素,这一过程会经过系统的计算转化,比如可能是四个实际的物理像素代表一个虚拟的设备独立像素);还有一个不错的解释是:设备独立像素,处于实际屏幕和开发的css网页之间

(3) 设备像素比率(Device Pixel Ratio,DPR):物理像素/设备独立像素,不同的设备有着不同的DPR,通过这个参数可以区分开retina屏幕和非retina屏幕。所有的非retina屏幕的iPhones有着一个物理宽度为320的屏幕,当设置它的meta信息为的时候,这将会设置layout viewport为320像素,所以整个页面将会自然的充满整个屏幕。因此,它有着320的物理像素和320的DIP,所以它的DPR即为1。而对于retina屏幕的iPhones有着一个物理宽度为640,但是同时若拥有一样的meta信息,则layout viewport的宽度不变,所以最后计算出来的DPR则为2,当然还有其他数值的DPR。这个信息可以通过在浏览器中读取window.devicePixelRatio属性来获取,不过存在着一些兼容性的问题

##关于viewport##

关于viewport的由来,貌似是苹果开始的,具体可以google看看,而现在则是由所有手机都支持了,关于viewPort分为两部分,分别是layout viewport && visual viewport

首先介绍下这两种的形象的概念,这个貌似是在stackOverflow上有大神的回复;以下是参考链接中一个博主对他的翻译

layout viewport想像成为一张不会变更大小或者形状的大图。现在想像你有一个小一些的框架,
你通过它来看这张大图。(译者:可以理解为「管中窥豹」)这个小框架的周围被不透明的材料所环绕,
这掩盖了你所有的视线,只留这张大图的一部分给你。你通过这个框架所能看到的大图的部分就是
visual viewport。当你保持框架(缩小)来看整个图片的时候,你可以不用管大图,或者你可以
靠近一些(放大)只看局部。你也可以改变框架的方向,但是大图(layout viewport)的大小和
形状永远不会变。

###1. visual viewport
根据字面就是可视的viewport,按照上面说的那个比喻,这个viewport就是限制你视觉范围的那个框,这个viewport跟文档的宽度没有关系

对于visual viewport,它是通过window.innerWidth/Height来进行度量的。很明显当用户缩小或者放大的时候,度量的尺寸会发生变化,因为屏幕上的CSS像素会增加或者减少

个人的理解:我感觉这个viewport对我们影响并不大,在列出几个stackoverflow上对这个的回答

The visual viewport is the part of the page that’s currently shown on-screen. 
The user may scroll to change the part of the page he sees, or zoom to change 
the size of the visual viewport.

###2. layout viewport###

好了这个viewPort还是很重要的,可以字面来进行理解,就是布局的viewport,也就是整个document的,如果不手动设置,那么不同的设备会有不同的默认数值,比如Safari iPhone: 980px,Opera: 850px,Android WebKit: 800px,IE: 974px,可能还有其他的数值,所以一般在移动端的时候都需要对其进行设置(通过meta中的viewport来设置),好了,那么问题来了,这个数值应该设置为多少?

(1) 个人猜想:我的理解是layout viewport是作为整个document的宽度来设置(其实开发者比较关注的是宽度,高度貌似不是很在意),比如你完全可以设置layout viewport的宽度是900px,然后在定义一个container为780px,再对他进行全局的居中,即可

注意:经过实验测试,这个一开始的宽度是不能超出不同设备原来定义的layout viewport的宽度,其实可以可以超出去,只是会有一个overflow:visible的效果,可以试试在iphone5上,定义meta中width为1000px,会看到一个左右移动的类似overflow:visible的效果.也很好理解,系统默认的一个layout vireport一个宽度,然后你定义了一个后等于是在他的容器内部

(2) 实际情况:在meta中设置width:device-width;而且会设置一些类似initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no的属性,一般的移动设备的width都是320,当然也有不是的

好了,那么问题又来了,要是视觉姐姐给的图是320px的,那托托没问题的,按照里面的来就好了(就算你是把页面写死成320px的也ok),but,他们还经常给640px的,要是还是写死成640px,那么,都超出了layout viewport的宽度了诶,至于解决方案么还是有很多的,比如你可以用100%来定位等等,其实这些都不怎么好,推荐一个方法就是使用rem,可以看看阿里无线端的一个ml库,不错

写在最后,其实我没有特别去整理一些公式什么的,以上都是一些对于概念的整理.从小语文学的特别烂,估计这表述也就自己看看了.不过参考文章还是不错的

##参考##

  1. Retina显示原理探索
  2. 设备像素比devicePixelRatio简单介绍
  3. 两个viewport的故事(第一部分)
  4. A tale of two viewports — part one
  5. 两个viewport的故事(第二部分)
  6. A tale of two viewports — part two
  7. 不是像素的像素不是像素
  8. DESIGNER’S GUIDE TO DPI说的挺详细的,赞
  9. 两个viewport的故事(二) 感觉这个版本说的不错.貌似比3好
  10. csdn 上一个博主关于viewport的整理 分了四篇,前两篇同上,后面两篇不错,可以看看,第四篇貌似加了浏览器底层的原理来介绍;第三篇介绍的是关于position:fix的问题
  11. 此像素非彼像素其实跟文章5一样,只不过这里还有译者的一些理解
  12. 关于两个viewport的答案
  13. Viewport在苹果官方文档上有关viewport的介绍
  14. google 对viewport的介绍