关注【搜狐技术产品】公众号,第一时间获取技术干货
1 导读
viewport是移动端跨屏适配的基石,吃透这一概念,任何复杂多变的适配需求,都可以手到擒来。
移动端开发中,有一个躲避不掉的HTML meta 声明<meta name="viewport"> 。通常被用来做跨屏适配,常见声明如下:
1<meta
2 name="viewport"
3 content="width=device-width,initial-scale=1,user-scalable=no"
4/>
这个声明中隐含的概念、历史和未来,以及如何更合理的搭配%/px/rem/vw 来做跨屏适配,我们接下来一起探讨一下。
本文关键词:移动端适配、Viewport、Viewport Meta Tag、DPR、响应式、自适应、Viewport Units
2 viewport 概念
viewport 中文译作“视口”。
维基百科①的解释为:
在计算机图形学理论中,当将一些对象渲染到图像时,存在两个类似区域的相关概念。(视口和窗口)
视口是一个以特定于渲染设备的坐标表示的区域(通常为矩形)。视口范围内的图像会以剪切的形式,投影到到世界坐标窗口中,完成图像的可视化展示。
在 Web 浏览器中,视口是整个文档的可见部分。如果文档大于视口,则用户可以通过滚动来移动视口。
白话描述一下:
●计算机把图像渲染到显示器的过程中,会先把图像画在一个逻辑层的画布上,然后从这个画布中框选一部分,将其投影到显示层。
●这个选框就是视口,显示层就是窗口。
●在浏览器中,我们可以通过滚动条来移动视口以看到更多网页内容。
更形象的视口解释:
如这张某宝的商品放大效果图,左半图为计算机看到的逻辑层画布,上方半透明选框为视口(viewport),右半图为浏览器窗口,即用户看到的部分。
逻辑关系简单清晰。
此处插入一个问题:
浏览器中,对页面进行放大的时候,视口的大小如何变化?
2.1 viewport 的缩放与平移
回答上面的问题,视口会变小。
因为,浏览器窗口中所浏览图像的放大,是依赖于视口的缩小来实现的。
如果不好理解,可以参照下图动画来感受一下。(上面蓝框表示底层画布、红框表示视口,下面表示用户在浏览器窗口中看到的页面)
同理,当浏览器窗口比较小,而我们想要看到页面下面的内容时,我们需要向下滚动滚动条,浏览器在实现这个的过程中所依赖的,便是视口的下移。
2.2 viewport的DOM API
关于上面的解释,我们来验证一下。
目前已被标准实现的 API 中,有两个 DOM 属性可以用来获取视口的大小。
以宽度为例:
●document.documentElement.clientWidth(不含滚动条)
●window.innerWidth(含滚动条)
如图,PC Chrome 中试验,确实如之前解释,放大到 200%后,视口大小缩小了一倍。(小数点默认四舍五入了)
注意:
在移动端的浏览器中,对页面手动捏合做放大时,document.documentElement.clientWidth 不会有任何变化。window.innerWidth在 iOS 中会等倍数缩小,在 Android 的不同浏览器中表现差异较大。
如果有需要获取初始视口宽度的需求,建议使用document.documentElement.clientWidth ②。
3 移动端的 viewport
看起来 viewport 并没有太多复杂之处,但是 2010 年左右,移动端时代来了。
注:移动设备的显著特点是屏幕小,考虑到国际社会通行的水平阅读习惯,下文我们只讨论宽度。
3.1 窄屏设备的问题
移动互联网的早期,屏幕设备的物理像素点宽度多数在 320、480、640 等。而互联网世界的绝大多数站点又是针对 PC 设计的,其文档宽度普遍在 800px 以上。
如果浏览器和针对 PC 制作的网页都不做任何处理,那么在窄屏设备上加载网页,我们看到的效果便是默认显示网页的左上角部分,然后通过水平和竖直方向的滚动来浏览网页的其他部分。
首先,我们看不到网页全局的样子。其次,我们需要通过不断的滚动来保证阅读内容的连续性。这样的体验,有点过于糟糕了。
3.2 放大的viewport
为了优化“最初为 PC 设计的网页”在移动设备的浏览体验,移动浏览器厂商们想了一个方案,那就是增大页面载入时初始视口的宽度,比如 Android 和 iOS 都比较常见的 980px。
按照 2.1 里的 viewport 的解释,如此的设计,会把逻辑层画布中 980px 的图像投影显示到 320px 的屏幕上,看到的效果便是一个挤在一起看不清楚细节的缩小版页面。