关于响应式开发中的 viewport概念、像素比、缩放比 简述

1. viewport影响着我们页面的什么?

viewport是虚拟显示视口,它是时刻存在的【这一点有异议,有的人说必须要设置meta标签才会存在viewport,然而在chrome浏览器的调试工具中,添加和不添加meta标签都会触发viewport的行为】,我们设置meta标签只是去改变viewport的相关属性,并非是去设置一个viewport。只是在响应式页面开发过程中,默认的viewport会造成我们页面观感不合适,所以要去设置默认的缩放比例,以及viewport默认宽度,来适应响应式的开发。

关于虚拟窗口,MDN上做了如下解释:

窄屏幕设备(如移动设备)在一个虚拟窗口或视口中渲染页面,这个窗口或视口通常比屏幕宽;然后缩小渲染的结果,以便在一屏内显示所有内容。然后用户可以移动、缩放以查看页面的不同区域。例如,如果移动屏幕的宽度为640px,则可能会用980px的虚拟视口渲染页面,然后缩小页面以适应640px的窗口大小。

总结一下,当一个页面将要展示到我们的手机上时,页面会先在viewport中渲染,假如说我们没有设定viewport的宽度,页面会按照默认的980px的宽度去渲染(想象一下把你的浏览器窗口缩小为980px的宽度,你所看到的效果就是viewport中的渲染效果),然后渲染好的页面会被缩放显示到我们的设备上(想象一下把你缩小为宽度为980px的浏览器上的画面,塞到你的手机中)。

我们来看一组示例(默认viewport):

<style>
    .topbar {width: 100%;height: 200px;background-color: pink;}
    .container{width: 300px;height: 300px;background-color: skyblue;margin: 0 auto;}
  </style>
<body>
  <div class="topbar"></div>
  <div class="container"></div>
</body>

看起来布局上似乎很完美,但当我们添加上文字后,在我们的手机上就会这样显示:

文字内容简直小的可怜,这就是为什么我们不愿意去使用默认的viewport:他会无视我们手中实际设备的宽度去按照960px的宽度渲染页面,然后将渲染好的页面进行缩放再塞入我们的手机显示器,导致页面被缩放的过小。假入我们此时规定viewport的宽度与设备宽度相等,如下加入meta标签:

<meta name="viewport" content="width=device-width, initial-scale=1">

对于iPhoneSE来说,它的宽度为320px,那么viewport就以320px的宽度去渲染页面而非980px,之后渲染好的页面就不会被缩放,而是直接显示在我们的手机上,如下效果:

当然,我们也能看出,我们再下方定义的固定宽高的div,也同样会被缩放,这就是为什么我们推荐在响应式开发中使用半分比宽度而非绝对宽度,这会导致元素的缩放不合理,当有元素超过我们的viewport宽度后,viewport机制就会错乱,分为以下两种情况(针对Chrome和最新的Android Webview):

  • 如果我们设置了viewport,此时固定元素宽度如果大于设置的viewport宽度,viewport的宽度会回变化为页面最宽的元素,来显示过宽的元素,但是如果宽度设置为100%的元素,宽度仍保持原有的viewport宽度。

将Div#container宽度设置为400px

  • 当最宽的元素宽度大于980px(或者我们设置的最大viewport宽度),就会出现横向滚动条来显示我们页面中最宽的元素。

2. 什么像素比和物理像素?

像素比(dpr) = 物理像素 / css像素

通过 window.devicePixelRatio 获得当前设备的DPR

如:iPhoneX的DPR为3,iPhone5 Se的DPR为2,正常显示器的DPR为1

拿iPhoneSE来说,我们都知道iPhoneSE的分辨率为640 x 1136,而如果我们使用chrome调试工具将页面切换为移动端设备视图,我们会发现chrome显示的设备分辨率为320 x 568
调试工具界面
这是因为我们在手机上定义像素如果还按照大屏显示器那样去规定像素的话,文字、识图都会看起来小到无法识别(想象一下你将显示器缩小为如同手机那样的大小你还能看清屏幕上的文字吗),所以我们规定了一个缩放比来优化显示效果。

iPhoneSE的缩放比为2,那么我们将它的物理像素统统除以2,得到的结果便是 320 x 568 ,即一个实际像素显示2个物理像素。

1px指的是CSS像素

3. 计算页面元素真实的物理像素

那假如我们再页面上定义了一个200px宽高的div,那么它在iPhoneSE上显示的实际大小为多少呢。

  1. 如果我们不定义viewport,viewport在所有的显示设备上的显示宽度均为980px。那么在iPhoneSE上,我们看到的定义的200px宽高的元素的实际物理像素宽高为 640*(200/980)px

viewport默认宽度

  1. 如果我们定义了viewport的宽度为设备宽度,那么在iPhoneSE上,我们看到的定义为200px宽高的元素的实际物理像素宽高为 640*(200/320)px,即为 CSS像素*DPR

定义viewport宽度为设备宽度

4. 何为缩放比

缩放比即为我们再meta标签中设置的 initial-scale。它指的是当我们用移动设备去查看页面时,页面会被放大的倍数,只在我们设定viewport宽度后生效。

比如,当我们定义,如下meta标签,显示在ipad等移动设备上页面会被放大两倍:

<meta name="viewport" content="width=device-width, initial-scale=2">

桌面显示器显示效果

ipad显示效果

那缩放比具体有什么卵用呢?

当我们浏览一个移动端页面,针对页面上的一个按钮,如果不设置缩放,iPhoneSE和iPhone6 Plus会按照同样的按钮大小去展示。但这样的话iPhone6 Plus由于屏幕更大,显示按钮就会显得过小,观感上很不协调,所以我们这时候就可以将其缩放比设置为 414/320 即为 1.29 ,即代表这个按钮在iPhone6 Plus上会按照1.29倍等比例放大,这样整个页面的观感就会更好。

当然如果我们采用 rem 机制去动态改变元素的宽高和字体大小,也能达到同样的效果。

发布了48 篇原创文章 · 获赞 28 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/u012925833/article/details/89281992