天天看点

移动端像素与viewport原理

引言

移动端开发时会涉及到viewport的问题,做项目时加个meta标签就可以了,不过还是需要了解一下原理,不然在1px像素问题上的解决就不能理解

像素

当拿到ued给的移动端稿时,上面写着86px,如果真把一个div设为height:86px,就会高很多。这就是物理像素dp和像素px的区别,ued给的是物理像素,而我们在css中设置的是逻辑像素,他俩之间有个转换关系dpr

【像素px】: 逻辑像素,在不同设备上可大可小,浏览器使用的抽象单位

【 物理像素dp,pt】: 设备像素,固定大小

【设备像素缩放比】dpr:

1px=dpr^2*dp

以iphone5为例子

物理像素640dp * 1136dp (百度一下)

移动端像素与viewport原理

逻辑像素320px * 568px (打开谷歌浏览器开发者模式手机模式)

移动端像素与viewport原理

dpr=2

1css像素=4设备像素 (面积上)

在长度上设置时候

1css=2设备

所以刚才举的例子,ued给的86像素,我们在css中设置为height:43px即可

ppi: 屏幕每英寸的像素数量
移动端像素与viewport原理

【注意】:算ppi用物理像素算,而不是px

ppi越高,像素数越高,图片越清晰

调节pc分辨率的时候,可以发现,分辨率调得越高越清晰,但屏幕上的icon越小

移动端像素与viewport原理

屏幕上的icon越小,也就是系统默认缩放比越大,以下有四种维度的ppi缩放比

移动端像素与viewport原理

之前算过IPhone5的ppi为326,属于超高清屏,大于320,缩放比为2,dpr=2

理清一下关系

移动端像素与viewport原理

可以看这篇文章 移动设备分辨率(终于弄懂了为什么移动端设计稿总是640px和750px)

三个viewport

手机浏览器默认为我们做两件事情

  1. 页面渲染在一个980px的viewport(ios)
  2. 缩放

    如果不用viewport直接缩放,排版就会乱掉,所以为了排版正确,伪造了一个980的布局viewport

    移动端像素与viewport原理
    手机屏幕分为两层,底层是布局viewport(980px)负责渲染页面,上层是我们通过缩放控制的视口viewport
  • visual viewport:视口/度量viewport
  • layout viewport:布局viewport
  • 查看layout viewport: document.body.clientWidth
  • 查看visual viewport:window.innerWidth

为了验证,我把我的刚创建的项目中对viewport的meta标签设置去掉,打开谷歌浏览器的手机模式,看到的是一个可以在大页面挪动的手机视窗

移动端像素与viewport原理

右移一下

移动端像素与viewport原理

这就验证了底层是布局viewport(980px)负责渲染页面,上层是我们通过缩放控制的视口viewport

如果用980的layout viewport

移动端像素与viewport原理

页面需要缩放

所以不用默认的980px的布局viewport,会使用meta标签对其设置

【为什么不用默认的980px的布局viewport 】

宽度不可控制,不同系统的默认值可能都不同

页面缩小版显示,不友好

链接不可点

有缩放,缩放后又有滚动

因为不用980px布局viewport, 所以就需要用到meta标签来设置布局viewport

移动端像素与viewport原理

以iphone5为例,设置< meta name=‘viewport’ content=“width=320”>

这时候一张320px的图片可以填充完屏幕

因为手机各个不同,所以就用

< meta name=‘viewport’ content=“width=device-width”>

那为什么需要缩放比呢

比如我里面放一个610px的图片,那么visual viewport为610,layout viewport为320,缩放比不等于1

效果:

移动端像素与viewport原理

可以在console中看出:layout viewport为320,visual viewport为610,此时页面可向右滑动出剩余的div,也可以缩放

如果加一个对缩放比的控制,那么布局变化和视口变化都是320,不可向右滑动

< meta name=‘viewport’ content=“width=device-width, initial-scale=1, user-scalable=no”>

  • 通过width=device-width让布局viewport=设备宽度
  • 通过initial-scale=1让视口viewport=布局viewport