viewport都在用,但详细分析的文章并不多。苹果官方的开发文档有一些介绍,但语焉不详,且和实际情况有不少出入。本文在iPhone4,iOS 5.01的环境下测试viewport在各种参数下的具体表现,供日后参考。错漏之处,敬请指正。
首先看一下官网说的几点结论(红色部分与实际情况有出入):
1、iOS的safari下viewport默认宽度为980px(btw:Opera 850px, Android 800px, IE 974px)。

2、最常用的width = device-width,其值实际为320px(除ipad外的所有iOS设备)。
3、如果只设置initial-scale = 1.0,则竖屏下为device-width(320px),横屏下为device-height(480px)。

4、如果只设置width = 320,则不论横竖屏宽度都会自动缩放到320px。

5、viewport最低宽度为200px。

6、同时设置width = 980 和initial-scale = 1.0。原文是这样说的:“Safari on iOS infers the height by maintaining a ratio equivalent to the ratio of the visible area in either orientation. Therefore, if the width is set to 980 and the initial scale is set to 1.0 on iPhone, the height is set to 1091 in portrait and 425 in landscape orientation.”恕我愚钝,实在不理解这个1091和425是根据怎样的一个ratio计算出来的。也实在看不懂下面两副示例图如何跟980,1091和425有半毛钱关系。望得道之人予以指点。

—————————————————————————————————————
下面开始验证。无意间google到几个专门测量viewport的页面:
http://www.adrianworlddesign.com/Viewport-Demo/metatag
http://philarcher.org/cgi-bin/doctype.pl
两个页面都可以自由设置viewport的参数,遗憾的是前一个页面的doctype在我的iphone上似乎不太兼容,viewport设置不能生效,而后者并没有提供任何直观测量页面宽度的元素。还是自己动手吧:
< !DOCTYPE HTML>
<html>
<head>
<meta name="viewport" content="initial-scale=1" />
<title>Viewport Test</title>
<style>
*{
margin:0;
padding:0;
}
body>div{
font-size:48px;
height:80px;
margin-bottom:80px;
font-weight:bold;
text-align:center;
}
.w980{
background:#EB8F00;
width:980px;
}
.w640{
background:#2E6E9E;
width:640px;
}
.w320{
background:#4CA20B;
width:320px;
}
</style>
</head>
<body>
<script>
var width = window.innerWidth;
document.write('<div style="border:1px solid #000;width:'+(width-2)+'px">'+width+'px</div>');
</script>
<div class="w980">980px</div>
<div class="w640">640px</div>
<div class="w320">320px</div>
</body>
</html>
测试使用adobe shadow,这实际上是一个免费的weinre的GUI工具,非常方便调试移动页面。使用方法也很简单,就是手机上装一个app,然后在pc上运行一个监听程序,chrome上装一个扩展,配对后即可自动同步显示页面并实时inspect。官方视频教程在此,一看就会。
—————————————————————————————————————
Test Case 1:只设置initial-scale
| initial-scale | 横屏 | 竖屏 |
| 0.5 | 640px | 640px |
| 1 | 320px | 320px |
| 2 | 160px | 160px |
| 3 | 107px | 107px |
结论显而易见:无论页面宽高,width始终为device-width/X。与官方说法并不一致(The viewport width is set to device-width in portrait orientation and device-height in landscape orientation.)。
—————————————————————————————————————
Test Case 2:只设置width
列表测试的过程中很容易发现一个问题:只设置width时viewport的实际宽度还会受页面尺寸的影响!
当页面不超宽或超宽不超高时,宽度尚能维持在设定的width值,否则viewport的宽度将按比例缩小到垂直无需滚动或为980px为止,且此时screen.width/screen.availWidth/window.outerWidth/window.innerWidth/document.body.clientWidt等都无法反映正确的可视宽度。
为了简化测试,我们去掉供对比用的三个div元素,使以下测试结果皆在页面不超高的前提下得到。
| viewport宽度 | 横屏 | 竖屏 |
| 200 | 200 | 200 |
| device-width/320 | 320 | 320 |
| 480 | 480 | 480 |
| 640 | 640 | 640 |
—————————————————————————————————————
Test Case 3:同时设置width和initial-scale
| width/initial-scale | 横屏 | 竖屏 |
| 320/1 | 320 | 320 |
| 640/1 | 640 | 640 |
| 320/2 | 160 | 160 |
| 640/2 | 160 | 160 |
结论同样单纯无比:只有initial-scale有效。
—————————————————————————————————————
基于上述结论,我们需要两个准确的解决方案。千变万化的布局,放到手机上其实只有两种:
1、缩放自适应
2、响应式布局
第一种,缩放自适应的页面, 可以使用
<!--最普通最常见的用法--> <meta name="viewport" content="width=device-width" /> <!-- 如果有足够的高清图资源,主要支持retina设备(ip4/4s),那么推荐下面这种--> <meta name="viewport" content="width=640" /> <!-- 如果针对new iPad,甚至可以试试这个--> <meta name="viewport" content="width=1536" />第二种,复杂的响应式布局,实际就是要求页面在切换横屏时不放大,从而留出空白用以填充或调整列布局。
此时可以看到无论width还是initial-scale都无法限制横屏时的放大,因而必须用上minimum/maximum-scale,而width和initial-scale则推荐使用initial-scale,使三个scale参数统一。
<!--最普通最常见的用法--> <meta name="viewport" content="initial-scale=1,maximum-scale=1,minimum-scale=1" /> <!--for retina screen--> <meta name="viewport" content="initial-scale=0.5,maximum-scale=0.5,minimum-scale=0.5" />