Meta Viewport

译者序

Ivan Yan 翻译,译文版权"署名-非商用",意见反馈

注意这是选译,不包含兼容性表等内容,请同时参看原文

正文

这里不研究 @viewport,等我弄明白它是怎么回事之后再说。

<meta viewport> 最开始是由 Apple 为 iPhone 发明的。随着它被广泛使用,其它移动浏览器也实现了它,包括它的不合理部分。

同时 W3C 也制作了一份规范。尽管我愿意了解它,以对比我的发现,但是它的内容恐怕我不能理解,即便是现在我已经理解 <meta viewport> 了。例如,我认为 W3C 的一个概念 extend-to-zoom 跟我说的 ideal viewport 意思一样,不过我不能完全确认。所以我希望这篇文章可以作为这份规范的一份英语翻译,不过我不能确信。

<meta viewport> 指定浏览器的 viewport 与缩放。特别是开发者可以用它设置 layout viewport 的宽度——CSS 的声明比如 width: 20% 基于这个宽度计算。

它有下面的语法:

<meta name="viewport" content="name=value,name=value">

指令

每对 name/value 是一个指令(指令 directive,这是我的自创词)。共有 6 个:

device-width

width 特殊值:device-width,设置 layout viewport 宽度为 ideal viewport 的宽度。

理论上类似的也有个 device-height,但是它的效果不如预期。

三种 viewport

几年前我报告了移动浏览器有两种 viewport: visual viewport 和 layout viewport。如果不清楚请再看一遍。

ideal viewport

还有第三种 viewport,我称之为 ideal viewport,即页面在设备上的理想尺寸。因而它的尺寸随设备的不同而不同。

旧的或便宜的设备,不是视网膜屏的,它的 ideal viewport 等于设备的物理像素值。新的设备,有更高的物理像素密度,仍然保持旧的 ideal viewport,因为它是设备的理想适配。

iPhone 4s 及之前的版本,不管它是不是视网膜屏,ideal viewport 都是 320x480。这是因为 320x480 是 iPhone 上页面的理想尺寸。

关于 ideal viewport 有两个要点:

获得 ideal viewport 的尺寸

能够获得 ideal viewport 的尺寸有时会有用处,不过这需要运气。

嗯,你能做到。假设一个页面有下面 <meta>,并且获得 document.documentElement.clientWidth/Height:

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

不是这样的话就没有办法获得 ideal viewport 的尺寸。我希望这里能用上 screen.width/height,但是只有 BlackBerry 给出正确的值。

开放问题:screen.width/height 应当给出 ideal viewport 的尺寸吗?正方:这两个属性至少将包含有用的信息。反方:ideal viewport 没必须等于物理像素值。

最大与最小尺寸

layout viewport 的最大尺寸是 10,000px,我不完全相信这个数值,因为浏览器不能放大到这么大。

layout viewport 的最大尺寸是 ideal viewport 的 1/10,这也是最小缩放(0.1)。例外:Android WebKit 与 IE 不能小于 320px。

缩放

缩放让人难以捉摸。理论上很简单:确定缩放系数(zoom factor)。问题有二:

然后是名字。Apple 将 zoom 称为 scale, 因而 <media viewport> 的指令也这样称呼:initial-scaleminimum-scalemaximum-scale。为了兼容适配 iPhone 的网站,其它浏览器也只好这样。

这三个指令需要一个缩放系数,例如 “2”, 意思是放大到 ideal viewport 的 200%。

公式

先定义公式:

visual viewport width = ideal viewport width / zoom factor
zoom factor = ideal viewport width / visual viewport width

因此,若 ideal viewport 的宽为 320px,缩放系数为 2,则 visual viewport 的宽为 160px。这里不考虑 layout viewport。

最大与最小缩放系数

浏览器支持的最大与最小缩放系数是多少?

首先一个限制是 visual viewport 永远不能比 layout viewport 更宽,因而在大多数情况下最小的缩放系数是 ideal viewport width / layout viewport width。

理论上 iPhone 的 visual viewport 宽度最小为 32px (缩放系数为 10),最大为 3200px (缩放系数为 0.1)。

initial-scale

initial-scale 做了两件事:

比方说,iPhone 竖屏 initial-scale=2,即设置 visual viewport 宽度为 160px(=320/2)。这便是 scale 指令如何作用的。

但是,它也设置 layout viewport 宽度为 160px。因此我们得到宽 160px 的页面。这是最小缩放。visual viewport 不能比 layout viewport 更宽,所以不能再缩小。

矛盾

既然 initial-scale 设置了 layout viewport 宽度,可以创建下面矛盾的指令:

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

浏览器得到矛盾的指令。让我们再次回到 iPhone 4s:

  1. initial-scale=1 告诉它设置 layout viewport 宽度:竖屏 320px,横屏 480px。
  2. width=400 告诉它设置 layout viewport 宽度:横竖屏都为 400px。

浏览器的应对措施是使用最大的宽度。在我们的例子中,竖屏宽 400px(300,400),横屏宽 480px(480, 400)。

有道理吗?当然没有,但是浏览器就是这么做。

假如这里是 min-width,最小宽度为 400px,而且允许浏览器随需要扩大 layout viewport。

我不确定对 layout viewport 使用 min-width 有什么实践意义,不过如果你需要,它就在那里。

minimum/maximum-scale

对于 minimum-scalemaximum-scale,我只做了少量测试。似乎没啥问题,有两个例外。Android WebKit 不支持 minimum-scale。IE,一团糟。实际上我放弃去弄清楚它们了。