由 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 个:
width
设置 layout viewport 的宽度。initial-scale
设置页面初始缩放级别,以及 layout viewport 宽度。minimum-scale
设置页面最小的缩放级别。maximum-scale
设置页面最大的缩放级别。height
设置 layout viewport 的高度,不是全都支持。user-scalable
当为 “0” 时阻止用户缩放,绝对不要用。width
特殊值:device-width
,设置 layout viewport 宽度为 ideal viewport 的宽度。
理论上类似的也有个 device-height
,但是它的效果不如预期。
几年前我报告了移动浏览器有两种 viewport: visual viewport 和 layout viewport。如果不清楚请再看一遍。
还有第三种 viewport,我称之为 ideal viewport,即页面在设备上的理想尺寸。因而它的尺寸随设备的不同而不同。
旧的或便宜的设备,不是视网膜屏的,它的 ideal viewport 等于设备的物理像素值。新的设备,有更高的物理像素密度,仍然保持旧的 ideal viewport,因为它是设备的理想适配。
iPhone 4s 及之前的版本,不管它是不是视网膜屏,ideal viewport 都是 320x480。这是因为 320x480 是 iPhone 上页面的理想尺寸。
关于 ideal viewport 有两个要点:
width=device-width
及 initial-scale=1
。scale
是相对于 ideal viewport,与 layout viewport 无关。因此 maximum-scale=3
意思是最大可以放大到 ideal viewport 的 300%。能够获得 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-scale
,minimum-scale
,maximum-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
做了两件事:
比方说,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:
initial-scale=1
告诉它设置 layout viewport 宽度:竖屏 320px,横屏 480px。width=400
告诉它设置 layout viewport 宽度:横竖屏都为 400px。浏览器的应对措施是使用最大的宽度。在我们的例子中,竖屏宽 400px(300,400),横屏宽 480px(480, 400)。
有道理吗?当然没有,但是浏览器就是这么做。
假如这里是 min-width
,最小宽度为 400px,而且允许浏览器随需要扩大 layout viewport。
我不确定对 layout viewport 使用 min-width 有什么实践意义,不过如果你需要,它就在那里。
对于 minimum-scale
和 maximum-scale
,我只做了少量测试。似乎没啥问题,有两个例外。Android WebKit 不支持 minimum-scale
。IE,一团糟。实际上我放弃去弄清楚它们了。