移动前端中 viewport (视口)

一、viewport的概念

PC端

viewport实际上等于浏览器窗口,拥有浏览器窗口的宽度和高度,<html>元素使用viewport宽度的100%(在未手动设置html元素宽度情况下)。用document.documentElement.clientWidth获取viewport的宽度。用document.documentElement.offsetWidth获取<html>元素本身的尺寸

移动端

分为visual viewport、layout viewport和ideal viewport。
关于visual viewport和layout viewport两者解释请看两个viewport的故事(第二部分)文章的viewport板块。关于ideal viewport的解释请看Meta viewport (视口元信息标签)。ideal viewport大小由设备本身决定。

CSS布局,尤其是百分比宽度,是以layout viewport做为参照系来计算的。所以<html>元素在初始情况下用的是layout viewport的宽度。

当进行缩放(如果你放大,屏幕上的CSS像素会变少)的时候,visual viewport(就是页面当前显示在屏幕上的部分)的尺寸会发生变化,layout viewport的尺寸仍然跟之前的一样。(如果不这样,你的页面将会像百分比宽度被重新计算一样而经常被重新布局。)

document.documentElement.clientWidth计算layout viewport的宽度。
window.innerWidth/Height或者document.documentElement.offsetWidth计算visual viewport的宽度
document.documentElement.offsetWidth计算<html> 元素的尺寸。

二、viewport meta标签

viewport meta标签用来设置layout viewport的宽度

initial-scale=1

visual viewport width = ideal viewport width / zoom factor
设置 initial-scale这条规则实际上做了如下2件事:
1、将页面初始缩放因子设置为给定的值,根据ideal viewport,计算得到visual viewport的宽。
2、设置layout viewport的宽等于刚刚计算出来的visual viewport的宽。
注意:对于IE,会获取一个错误的ideal viewport(320×320而不是320×480),并且会将任意值都当作成1,所以在IE上initial-scale取什么值都无所谓。

initial-scale=1可以将 layout viewport的值设置为 ideal viewport的大小。IE10上横屏模式和竖屏模式的宽都是竖屏时ideal viewport宽度。

width=device-width

width规则下有一个特殊的值device-width,通过设置width=device-width可以将layout viewport(布局视口)的宽度等于 ideal viewport(理想视口)的宽。

在iphone和ipad上,无论是竖屏还是横屏,宽度都是竖屏时ideal viewport的宽度。

initial-scale=1与width=device-width

1、使用 width=device-width 和initial-scale=1两个规则,可以将 layout viewport的值设置为 ideal viewport的大小。

2、所有的缩放规则都是相对于 ideal viewport而言的,而与layout viewport多宽无关。因此maximum-scale=3的含义就是页面最多放大到 ideal viewport的3倍。

width 和 initial-scale=1

当width 和 initial-scale=1冲突时,使用宽度最大原则(横屏或竖屏模式下均是)来解决,即哪个宽度大用哪个。

三、设备像素与CSS像素之间的换算是如何产生的

每英寸像素(pixel per inch)

ppi,表示每英寸所拥有的像素(pixel)数目,数值越高,代表显示屏能够以越高的密度显示图像。ppi的计算方式可以参考维基百科每英寸像素

设备像素比(device pixel ratio)

以上计算出ppi是为了得到密度分界,获得默认缩放比例,即设备像素比。
《移动前端中 viewport (视口)》

上图可知,ppi在120-160之间的手机被归为低密度手机,160-240被归为中密度,240-320被归为高密度,320以上被归为超高密度(Apple给了它一个高大上的名字——Retina)。

获得设备像素比后,便可得知设备像素与CSS像素之间的比例。当这个比率为1:1时,使用1个设备像素显示1个CSS像素。当这个比率为2:1时,使用4个设备像素显示1个CSS像素,当这个比率为3:1时,使用9(3*3)个设备像素显示1个CSS像素。

四、缩放实质

现代浏览器中实现缩放的方式无怪乎都是「拉伸」像素。

假设你给一个元素设置了width: 128px的属性,并且你的显示器是1024px宽,当你最大化你的浏览器屏幕,这个元素将会在你的显示器上重复显示8次(大概是这样;我们先忽略那些微妙的地方)。

如果用户进行缩放,那么计算方式将会发生变化。如果用户放大到200%,那么你的那个拥有width: 128px属性的元素在1024px宽的显示器上只会重复显示4次。元素的宽度并没有从128被修改为256像素,元素仍然是128个CSS像素宽,即使它占据了256个设备像素的空间。

参考自:
两个viewport的故事(第一部分)
两个viewport的故事(第二部分)
Meta viewport (视口元信息标签)

    原文作者:lijinxieyang
    原文地址: https://segmentfault.com/a/1190000008135021
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞