标点符(钱魏 Way)

使用viewport为移动设备做适配

设备像素和CSS像素

设备像素(device pixel, dp): 又称为物理像素。指设备能控制显示的最小物理单位,意指显示器上一个个的点。从屏幕在工厂生产出的那天起,它上面设备像素点就固定不变了,单位pt。pt 在 css 单位中属于真正的绝对单位,1pt = 1/72(英寸),而1英寸等于2.54厘米。所以设备像素的特点就是大小固定,不可变。比如 iPhone 5 的分辨率为 640 x 1136px.

CSS像素(css pixel, px): 又称为虚拟像素,也可以理解为直觉像素。CSS 像素是 Web 编程的概念,指的是 CSS 样式代码中使用的逻辑像素。在 CSS 规范中,长度单位可以分为两类,绝对(absolute)单位以及相对(relative)单位。px 是一个相对单位,相对的是前面所说的设备像素(device pixel)。比如 iPhone 5 的 CSS 像素数为 320 x 568px.

px 相对单位指的是图像显示的基本单元,作为一个抽象概念,CSS 像素又具有两个方面的相对性,即:

  • 在同一个设备上,每1个 CSS 像素所代表的设备像素是可以变化的
  • 在不同的设备之间,每1个 CSS 像素所代表的设备像素是可以变化的

所以,CSS中的1px(CSS像素 可变)!== 设备的1px(设备像素 不可变)。

在桌面浏览器中css的1个像素往往都是对应着电脑屏幕的1个物理像素,这可能会造成我们的一个错觉,那就是CSS中的像素就是设备的物理像素。但实际情况却并非如此,在不同的设备或不同的环境中,CSS中的1px所代表的设备物理像素是不同的。在为桌面浏览器设计的网页中,我们无需对这个津津计较,但在移动设备上,必须弄明白这点。

那么px 都会受哪些因素的影响而变化?

  • 每英寸像素(pixel per inch, ppi/PPI): 它表示的是每英寸所拥有的像素(pixel)数目,更确切的说法应该是像素密度,放到显示器上说的是每英寸多少物理像素及显示器设备的点距。数值越高,代表显示屏能够以越高的密度显示图像。
  • 设备像素比(device pixel ratio, dpr/DPR): 它描述的是未缩放状态下,设备像素和 CSS 像素的初始比例关系,也可以解释为默认缩放比例。通俗来说,它是指在开发中1个 CSS 像素占用多少设备像素,如dpr=2代表1个 CSS 像素用2×2个设备像素来绘制,所以,可以理解为1px由多少个设备像素组成。

DPI: 每英寸多少点。当用于描述显示器时,我们可以吧 ppi 和 dpi 认为是同一个概念。那么 ppi和dpr到底是什么关系呢?ppi用作显示设备的工业标准,业界人士用ppi的值来衡量一个屏幕是否为高清屏,然后根据得到的密度分界来获得此时对应的dpr值,也即默认缩放比例。dpr和ppi相关,一般dpr为ppi/160的整数倍,如下所示:

项名 ldpi mdpi hdpi xhdpi
密度分界(密度值) 120 160 240 320
屏幕尺寸(分辨率) 240×320 320×480 480×800 640×960
默认缩放比例 0.75 1.0 1.5 2.0

了解了这两个概念后,我们可以来说说导致 CSS 中 px 变化的因素了。

从 iPhone4 开始,苹果推出了 Retina 屏,分辨率提高了一倍(640*960),而屏幕尺寸却没变。这时一个css像素=2个设备像素(换算公式为 1px = (dpr)^2 * 1dp, 必须让css中的1px代表更多的设备像素,才能让1px的东西在屏幕上的大小与那些低分辨率的设备差不多,否则会因太小而看不清),即 DPR=2,示意图如下:

引起css中px的变化的因素还有用户缩放。例如,当用户把页面放大一倍,那么css中1px所代表的物理像素也会增加一倍;反之把页面缩小一倍,css中1px所代表的物理像素也会减少一倍。

如何理解上面说到的缩放呢?放大1倍,原来 1px 的东西变成 2px,但1px 变为 2px 并不是把原来的320px 变为640px,而是在实际宽度不变的情况下,1px 变得跟原来的 2px 的长度(长宽)一样了(元素会占据更多的设备像素),所以放大1倍后原来需要 320px 才能填满的宽度现在只需要 160px,也即原来 320px 的面积里现在只能填入 160px 的东西了。

什么是viewport?

viewport 是用户网页的可视区域。viewport 翻译为中文可以叫做“视窗“或”视区”。Viewport 虽然它只是一个单词,但它却囊括了三个方面。Viewport 分为:视觉视窗、布局视窗和理想视窗。

视觉视窗(visual viewport)

所谓的视觉视窗说白了就是设备的屏幕区域,换句话说就是用户通过屏幕所看到的页面内容。但它所对应的并不是指屏幕区域里的物理像素,而是CSS 像素。并且它所包含的 CSS 像素的数量也是随着用户缩放而有所改变。

布局视窗(layout viewport)

移动设备上的浏览器认为自己必须能让所有的网站都正常显示,即使是那些不是为移动设备设计的网站。但如果以浏览器的可视区域作为viewport的话,因为移动设备的屏幕都不是很宽,所以那些为桌面浏览器设计的网站放到移动设备上显示时,必然会因为移动设备的viewport太窄,而挤作一团,甚至布局什么的都会乱掉。所以这些浏览器就决定默认情况下把viewport设为一个较宽的值,比如980px,这样的话即使是那些为桌面设计的网站也能在移动浏览器上正常显示了。

布局视窗表示的是浏览器默认的viewport,一般情况下这个宽度要大于浏览器可视区域宽度。

创建移动设备的布局视窗宽度:

理想视窗(ideal viewport)

现在我们已经有两个viewport了:visual viewport(视觉视窗)和layout viewport(布局视窗)。但浏览器觉得还不够,因为现在越来越多的网站都会为移动设备进行单独的设计,所以必须还要有一个能完美适配移动设备的viewport。所谓的完美适配指的是,首先不需要用户缩放和横向滚动条就能正常的查看网站的所有内容;第二,显示的文字的大小是合适,比如一段14px大小的文字,不会因为在一个高密度像素的屏幕里显示得太小而无法看清,理想的情况是这段14px的文字无论是在何种密度屏幕,何种分辨率下,显示出来的大小都是差不多的。当然,不只是文字,其他元素像图片什么的也是这个道理。

理想视窗是为了布局视窗而生的,它其实就是变了尺寸的布局视窗。理想视窗就是把布局视窗调整到合适的状态,让页面有最好的表面效果,这也是它名字的由来。

理想视窗并没有一个固定的尺寸,不同的设备拥有有不同的ideal viewport。所有的iphone的ideal viewport宽度都是320px。但是安卓设备就比较复杂了,有320px的,有360px的,有384px的等等,关于不同的设备ideal viewport的宽度都为多少,可以到http://viewportsizes.com去查看一下,里面收集了众多设备的理想宽度。

利用meta标签对viewport进行控制

meta viewport 标签首先是由苹果公司在其safari浏览器中引入的,目的就是解决移动设备的viewport问题。后来安卓以及各大浏览器厂商也都纷纷效仿,引入对meta viewport的支持,事实也证明这个东西还是非常有用的。

移动设备默认的viewport是layout viewport,也就是那个比屏幕要宽的viewport,但在进行移动设备网站的开发时,我们需要的是ideal viewport。那么怎么才能得到ideal viewport呢? 我们在开发移动设备的网站时,最常见的的一个动作就是把下面这个东西复制到我们的head标签中:

该meta标签的作用是让当前viewport的宽度等于设备的宽度(ideal viewport),同时不允许用户手动缩放。也许允不允许用户缩放不同的网站有不同的要求,但让viewport的宽度等于设备的宽度,这个应该是大家都想要的效果,如果你不这样的设定的话,那就会使用那个比屏幕宽的默认viewport,也就是说会出现横向滚动条。

在苹果的规范中,meta viewport 有6个属性,如下:

在苹果的规范中,meta viewport 有6个属性,如下:

内容 含义
width 设置layout viewport 的宽度,为一个正整数,或字符串”width-device”
initial-scale 设置页面的初始缩放值,为一个数字,可以带小数
minimum-scale 允许用户的最小缩放值,为一个数字,可以带小数
maximum-scale 允许用户的最大缩放值,为一个数字,可以带小数
height 设置layout viewport 的高度,这个属性对我们并不重要,很少使用
user-scalable 是否允许用户进行缩放,值为”no”或”yes”, no 代表不允许,yes代表允许

这些属性可以同时使用,也可以单独使用或混合使用,多个属性同时使用时用逗号隔开就行了。

利用CSS @VIEWPORT 做设备适配

在需要调整设备浏览器的viewport时,我们通常在HTML中使用来解决。但是令人意想不到的是,viewport meta标签并不具有“规范性”,即它不是W3C的正式标准,也非Web标准。W3C正在尝试规范一种新的设备适配方法的原因,将HTML对viewport的控制转交给CSS。

@viewport CSS 规则

使用@viewport规则控制viewport,与使用meta标签的效果相同,只是我们完全使用CSS来控制。与使用meta标签一样,仍然建议使用设备无关的值(device-width)来设置viewport宽度。

@viewport 描述符(Descriptors)

zoom描述符等同于viewport meta 标签的initial-sacale属性。

与minimum-scale, maximum-scale对应的描述符是max-zoom, min-zoom。

user-zoom与user-scalable属性等效。

由于目前各大浏览器对@viewport支持情况还不佳,目前阶段还是建议使用viewport meta 标签进行控制。

参考资料:

打赏作者
微信支付标点符 wechat qrcode
支付宝标点符 alipay qrcode
码字很辛苦,转载请注明来自标点符《使用viewport为移动设备做适配》

评论