β

《the mobile web handbook》读书笔记——再看viewport

携程UED 136 阅读

《the mobile web handbook》书中详细介绍了mobile端的三种viewport——布局viewport(layout viewport)可视viewport(visual viewport)理想viewport(ideal viewport)——以及与之相关的CSS和JS属性。本文前两部分来自该书viewport章节,介绍了初始包含块和三种viewport,鉴于三种viewport的概念比较抽象,本文最后一部分借助Chrome DevTool,图文并茂地将三种viewport介绍清楚。

初始包含块

在CSS中,如果未声明width,那么任何块级元素的默认宽度是其包含块宽度的100%。如果在CSS中,某元素声明width:35%,那么该元素的宽度就是其父元素的宽度的35%,若父元素未定义宽度,其宽度就为父元素的父元素宽度的100%,以此循环。若往上到达body,而body未声明宽度,于是其宽度为其包含块html的宽度的100%。若html也未声明宽度,那么html的宽度就是其包含块宽度的100%。那么html的包含块是什么呢?这里我们就来到了viewport。在CSS规范中,viewport被称为初始包含块。CSS中所有关于宽度的百分比均来源于初始包含块,同时,初始包含块将CSS布局限制在一个最大的宽度内。在桌面端,viewport的宽度就是浏览器窗口的宽度。因此,如果margin和padding都为0,htmlbody的宽度就是浏览器窗口的宽度。因此声明width:35%的元素其宽度未浏览器窗口宽度的35%。因此,初始包含块为页面布局提供了一个原始的尺寸,将页面限制在某一宽度内。这是PC端的情况,而在mobile端,情况就有所不同。

Mobile端的三种viewport

在移动端,如果初始包含块的宽度是屏幕宽度,那么声明width:35%的元素将被严重压缩。为了解决这个问题,浏览器厂商将移动端的viewport设置为一个更大的数值,一般介于768至1024之间,常见的viewport为980px。

也就是说,移动端的viewport不再与实际的移动端浏览器屏幕有关联,而是相互独立。这个viewport就被称为布局viewport,不过该viewport仍然将CSS布局限制在某一宽度,同时CSS中关于宽度的百分比大部分都来源于布局viewport。

尽管创建一个独立的布局viewport能将PC端的网站适配到移动端,但还是无法忽略移动设备的屏幕尺寸。这里,将用户当前看到的页面区域叫做可视viewport。可视viewport的尺寸跟移动设备的屏幕尺寸没有直接关系,用户通过缩放可改变可视viewport的尺寸,但出于设备性能的考虑,布局viewport不会重新计算,这是因为由于缩放在移动端的使用频率较高,如果布局viewport重新计算,设备的耗电量将大幅上升,因此mobile浏览器厂商会将布局viewport作为一个抽象层从PC端的viewport独立出来,使其不参与到用户的该交互行为。因此布局viewport尺寸不会受到影响。

默认的布局viewport并非理想的尺寸,于是Apple引入了理想viewport。它引入的目的是找到适合设备的布局viewport,对网站的宽度优化,使其适合浏览和阅读。

要获得理想viewport,其实我们已经很熟悉了,就是在html中加入以下meta标签:

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

它会告诉浏览器让布局viewport与理想viewport相匹配。

由于设备的物理尺寸不同,浏览器的理想viewport也有所不同,同时理想viewport会随着设备的手持方向而改变。

综上,在PC端,浏览器的窗口就是viewport,也就是初始包含块,它限制CSS布局的宽度,同时定义了用户当前所看到的区域。在mobile端,PC端的viewport一分为二:限制CSS布局的布局viewport;定义了用户当前看到区域的可视viewport。mobile端还有一个理想viewport,其尺寸与设备有关。通过meta viewport标签能将布局viewport设置为理想viewport,事实上响应式设计的基础就是它。

借助Chrome DevTool认识mobile端的三种viewport

借助Chrome DevTool,我们能更加清楚地理解mobile端的三种viewport。

当用PC端Chrome访问携程无线,会看到如下结果:

PC端Chrome访问携程无线

当打开Chrome DevTool,点击面板左上角的手机icon,这时就相当于用手机访问该网站了,得到的画面是一个布局挤压在设备屏幕内的网页:

viewport从PC到模拟手机的转变0.3

从图中可以看出,此时的缩放比为0.3,布局viewport(用红色边框圈出,下同。)的宽度为980px(在后面图中看得更清楚),可视viewport(用黄色边框圈出,下同。)的宽度为980px(从上面的横坐标读出),也就是当前页面的横向内容都在屏幕内。将页面放大到1.0,情况就有所不同了:

(可视)viewport从PC到模拟手机的转变1.0

此时页面不再挤压严重,而是清晰地展现出来。图片中深色背景(已用红框圈出)就是布局viewport,读取横坐标刻度发现它的尺寸并没有发生变化,宽度仍然是980px(高度仍然不变,不过已超过电脑屏高)。通过对比发现,可视viewport发生了变化:随着页面的放大,能在屏幕中显示的内容也越来越少,当放大到1.0时,可视viewport的宽度就随着横坐标的刻度变化从980px变为了320px。因此,在移动端,缩放会改变可视viewport的尺寸,从本质上说,缩放改变了屏幕中所能显示的CSS像素的多少,即可视viewport的尺寸,它与屏幕尺寸没有直接关系;布局viewport不会发生变化,其原因已在上一节提到。

以上过程模拟手机访问PC端的网站。从PC转为Chrome DevTool模拟手机的过程,布局viewport可视viewport的本质也逐渐显现。下面模拟手机访问移动网站,进一步认识这两个viewport以及理想viewport

接着上面,当从Chrome DevTool的设备模拟中选择Apple iPhone 5刷新页面得到的结果是:

模拟手机iphone 5

从图中看到,模拟设备下方深色部分就是页面的布局viewport:320px*680px,有伸缩功能的边框就是当前设备的理想viewport320px*568px,当模拟设备变为Google Nexus 4,其布局viewport变为384px*712px,理想viewport为384px*640px

模拟手机nexus 4

理想viewport会随着模拟设备的屏幕尺寸变化,相应地,由于meta viewport标签能将布局viewport设置为设备的理想viewport,布局viewport的宽度也随着理想viewport的宽度从320px变为384px

以上是将meta viewport设置为<meta name="viewport" content="width=device-width,initial-scale=1" />,若initial-scale=0.5,即<meta name="viewport" content="width=device-width,initial-scale=0.5" />,情况就有所不同。

initial-scale=0.5

Apple iPhone 5:页面缩放比为0.5的截图

Apple iPhone 5的布局viewport的宽度为320/0.5=640px,也就是initial-scale的取值会影响到布局viewport。由于初始状态的缩放比为0.5,页面内容不清晰,通过读取横坐标,此时的可视viewport的宽度和布局viewport的宽度一样,也是640px。当页面缩放比增加到1.0,屏幕所看到的内容变少,但更加清晰,可视viewport就从640px变为320px,如下图:

initial-scale=0.5,然后放大到1.0

Apple iPhone 5:页面缩放比为1.0的截图

总结

本文结合Chrome DevTool,对《the mobile web handbook》书中提及的移动端三种viewport(布局/可视/理想viewport)进行了一定深入的分析。根据本人理解,布局viewport与CSS布局直接相关,它限制了CSS布局;可视viewport与屏幕所能容纳的CSS像素多少有关,而与屏幕尺寸没有直接关系,通过缩放可改变;理想viewport来自meta viewport,它将页面布局viewport设置为设备适合的尺寸。希望通过此文能对移动端的viewport有进一步的了解。

感谢小志审阅。

作者:携程UED
携程旅行前端开发团队
原文地址:《the mobile web handbook》读书笔记——再看viewport, 感谢原作者分享。

发表评论