对于桌面浏览器,通常我们用 screen.width 和 screen.height 得到屏幕的大小,然后用 window.innerWidth 和 window.innerHeight(对于标准浏览器)或者 document.documentElement.clientWidth 和 document.documentElement.clientHeight(对于 IE8-)取得视区(viewport)的大小。知道了视区大小我们就可以让页面占满整个显示区域且不会出现窗口滚动条。对于桌面浏览器,默认视区大小一般总是小于屏幕大小的,因为还有操作系统和浏览器本身都要占用一定的空间。
而对于手机浏览器,我们用同样的方法也可以取得屏幕大小和视区大小。但是这时候大小可能反过来了:在 iOS 和 Android 中,默认视区大小经常要大于屏幕大小。在 Android 2.3 中,视区大小为 800x1003;Andoid 4.0 中,视区大小为 980x1234;在 iOS4 和 iOS5 中,视区大小为 980x1091。而得到的屏幕大小值,Android 手机各不相同,在 iPhone 中始终为 320x480。
在 iPhone 4/4S 中,屏幕的物理分辨率已经是 640x960 了,浏览器提供的屏幕大小数据还是 320x480。这是为了兼容性的考虑:保证为旧 iPhone 定制的网页在新 iPhone 中仍然能正常显示。这时候,新 iPhone 将在渲染时将把网页的1个像素对应4个物理像素来显示,从而文字将更加清晰锐利。但是对于图片,如果图片像素和它在网页中像素大小一样,看起来会比旧 iPhone 时丑陋。因此,对于新 iPhone,需要提供双倍长宽的图片才能利用它的高清屏幕。
为方便设置移动浏览器的视区大小,Apple 公司在 Mobile Safari 中引入了 viewport meta tag。这个标签同样被 Android 支持。例如,用下面的代码:
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1.0">
我们设定了视区宽度等同于设备宽度,而且页面的只能放大不能缩小。可以设定的选项还有这些:
|
描述 |
取值 |
|
视区宽度 |
device-width 或者像素值 |
|
视区高度 |
device-height 或者像素值 |
|
初始缩放比例 |
浮点值 |
|
最小缩放比例,默认为 |
浮点值 |
|
最大缩放比例,默认为 |
浮点值 |
|
用户是否可以缩放页面 |
yes 或者 no |
注意在前面的例子中,我们设定视区宽度等于设备宽度,这个值对于 iPhone 是 320px,而对于 Android 就有些复杂了。这时候,我们需要区分物理像素和设备像素,以及两者的比值 windows.devicePixelRatio。举例如下:
物理像素 |
设备像素 | devicePixelRatio | screen.width/height | |
iPhone 3GS | 320x480 | 320x480 | 1 | 320x480 |
iPhone 4 | 640x960 | 320x480 | 2 | 320x480 |
iPhone 5 | 640x1136 | 320x568 | 2 | 320x568 |
Samsung Galaxy Mini | 240x320 | 320x480 | 0.75 | 240x320 |
HTC Wildfire | 240x320 | 320x480 | 0.75 | 240x320 |
HTC Wildfire S | 320x480 | 320x480 | 1 | 320x480 |
Samsung Galaxy Ace | 320x480 | 320x480 | 1 | 320x480 |
Google Nexus One | 480x800 | 320x533 | 1.5 | 480x800 |
Samsung Galaxy S2 | 480x800 | 320x533 | 1.5 | 480x800 |
Motorola Defy | 480x854 | 320x569 | 1.5 | 480x854 |
Sony Xperia SX | 540x960 | 360x640 | 1.5 | 540x960 |
Samsung Galaxy S3 | 720x1280 | 360x640 | 2 | 720x1280 |
Samsung Galaxy Note2 | 720x1280 | 360x640 | 2 | 720x1280 |
HTC One X | 720x1280 | 360x640 | 2 | 720x1280 |
HTC Butterfly | 1080x1920 | 540x960 | 2 | 1080x1920 |
Sony Xperia Z | 1080x1920 | 540x960 | 2 | 1080x1920 |
可以看出,在高端的 Android 手机中,物理像素和设备像素基本和 iPhone 4 一样是2倍的比例了,但是两者的屏幕大小值表现方式不同:对于 iOS,screen.width 和 screen.height 等于设备像素值,而对于 Android,它们等于物理像素值。
上面的表格列举的仅仅是自带浏览器的结果。实际上,devicePixelRatio 值与浏览器也有关系。例如,Firefox 从 18.0 版本开始才支持这个属性;而 Opera Mobile 按照屏幕的 dpi 值来设置 devicePixelRatio,如下表:
屏幕 dpi 值 | windows.devicePixelRatio | 例子 |
0 - 170 | 1 | HTC Wildfire(240x320) |
170 - 200 | 1.25 | HTC Hero(320x480) |
200 - 260 | 1.5 | Samsung Galaxy S2(480x800) |
260 - 280 | 1.75 | Motorola Atrix 4G(540x960) |
280 - 320 | 2 | Sony Xperia Ray(480x854),Samsung Galaxy S3(720x1280) |
320 - ∞ | 2.25 | Samsung Galaxy S4(1080x1920) |
在 Opera Mobile 中,我们也可以在设置菜单的“缩放”选项里,改变 devicePixelRatio 值。
设置 width=device-width 时还需要考虑用户旋转屏幕的情形,详情可以见参考资料[M]。
在 Android 2.0 增加了 target-densitydpi 选项,用于设置像素密度。target-densitydpi 的取值有如下几种:
- device-dpi:使用设备的像素密度,不缩放
- high-dpi:针对高像素密度设备,在中像素密度和低像素密度的设备适当缩小
- medium-dpi:针对中像素密度设备,在高像素密度设备中适当放大,在低像素密度设备中适当缩小。这个是默认值。
- low-dpi:针对低像素密度设备,在高像素密度和中像素密度设备中适当放大
- dpi 值 :针对某个具体的像素密度值,该值必须在 70-400 之间
更新:如果要针对不同的设备设置不同 CSS 样式,可以参考 media type 和 media query 这篇文章。
2013年6月14日更新:Android 的 target-densitydpi 选项已经被废弃,详情见参考资料[F]。
参考资料:
[1] Browser compatibility — viewports
[2] A pixel is not a pixel is not a pixel
[3] A tale of two viewports — part one
[4] A tale of two viewports — part two
[5] Targeting Screens from Web Apps | Android Developers
[6] Safari Web Content Guide: Configuring the Viewport
[7] First, Understand Your Screen(result table)
[8] iPad Retina Display and Web Design
[9] Android web开发快速入门
[A] viewport ——视区概念
[B] Using the viewport meta tag to control layout on mobile browsers - Mobile | MDN
[C] Dynamically changing the meta viewport - QuirksBlog
[D] Safari HTML Reference: Supported Meta Tags
[E] W3C - CSS Device Adaptation #Viewport META element
[F] Viewport target-densitydpi support is being deprecated
[G] Web Design for Mobiles and Tablets – Viewport Sizes
[H] devicePixelRatio - QuirksBlog
[I] More about devicePixelRatio - QuirksBlog
[J] 设备像素比 devicePixelRatio 简单介绍
[K] Opera Developer News - devicePixelRatio in Opera Mobile
[L] An introduction to meta viewport and @viewport - Dev.Opera
[M] Technical Note TN2262: Preparing Your Web Content for iPad
[N] The Holy Grail of Mobile Layout | CSS3 Wizardry
[O] QuirksMode - Screen size tests