Device Pixel Ratio & Media Queries
一些重要的名词解释:
CSS pixels(CSS 像素):详见http://www.w3.org/TR/css3-values/#reference-pixe
CSS声明的像素值,可随着放大缩小而放大缩小。
Device pixels(设备 像素):
Layout viewport(布局视口)设计像素值固定,对web开发者来说基本没有用。
HTML元素初始视口区域,css中声明宽度的20%等都是按照这个视口来计算。
Visual viewport (设备视口)
屏幕视口,通过这个视口能看到页面布局。
关于移动设备:
有两个视口,Visual Viewport和Layout Viewport。Visual Viewport是页面在屏幕上显示的一部分,用户可以通过滚动来改变能看到的页面的部分,或者通过缩放来改变visual viewport的大小。Layout Viewport,可以比Visual Viewport宽,css中声明的百分比都按照Layout Viewport的宽高来计算。默认的Layout Viewport在各个浏览器上显示宽度略有不同,Safari iPhone 980px、Opera 850px、Android Webkit 800px、IE 974px。可见在初始化时的Layout Viewport宽度普片宽于Visual Viewport。有些浏览器有一些特别行为:
Browser | Behaviour |
Symbian Webkit | Layout viewport和Visual Viewport保持一致,因此Layout Viewport最宽不能超过850px |
Samsung Webkit(bada) | Layout Viewport和最宽的元素保持一致 |
BlackBerry | Layout Viewport和Visual Viewport 100%放大时一样。 |
缩放(zooming):
Layout Viewport和Visual Viewport都以CSS的像素来衡量,但当放大时(zoom in)屏幕中只能展现更少的CSS 像素值,但是layout viewport本身维度保持不变。
理解 layout viewport:
完全缩小模式:很多浏览器在页面初始的时候使用的是完全缩小模式(fully zoomed-out mode),就是说浏览器已经选择了layout viewport的尺寸去完全覆盖整个屏幕,等于visual viewport 。
因此在完全缩小模式下,layout viewport的宽度和高度和屏幕显示的相同,当用户放大时尺寸保持不变。Layout viewport 宽度总是保持不变的,如果旋转手机屏幕,visual viewport改变,但是浏览器为了适应旋转会稍微放大以保证layout viewport和visual viewport宽度一致。
但这也导致了一个问题:横屏模式下 layout viewport的高度远远屏幕高度,当然 大多时候we don’t care height.
测量 viewport:
有两个viewport需要测量-Layout Viewport 和 Visual Viewport。
Layout viewport 测量:document..documentElement.clientWidth (document.documentElement.clientHeight)
Visual viewport 测量:window.innerWidth(window.innerHeight) 显然,放大缩小时这个尺寸会变,更多或者更少的css 像素值在屏幕中显示,但这两个属性会有浏览器兼容性问题。
屏幕:screen.width(screen.height)
缩放等级:
可通过window.innerWdith除以screen.width来判断,前提你的浏览器得对这两个属性进行很好的支持╮(╯▽╰)╭,幸运的是~缩放等级不怎么重要。
Offset:
有时我们需要知道当前visual viewport相对于layout viewport的位置,即scrolling offset。
测量:window.pageXOffset(window.pageYOffset)
<html>元素:
测量:document.documentElement.offsetWidth(document.documentElement.offsetHeight)
Media Queries:
width(height)用于layout viewport,通过CSS像素值来衡量;device-width(device-height)用于设备屏幕,通过设备像素物理值来衡量。换句话说,
width(height)衡量的是document.documentElement.clienWidth(document.documentElement.clientHeight)
device-width(device-height)衡量的是screen.width(screen.height)
可以看出CSS Media Queries 在区分终端是desktop、tablet和mobile上还是很有用的,但不是不能区分使用mobile或者tablet的种类呦~。
事件坐标 :移动端各种不兼容哇。。。
pageX(pageY);clientX(clientY):相对于visual viewport而言;screenX(screenY):相对于设备屏幕以device pixels做衡量,米有什么用。
Meta Viewport:
大家应该都很熟悉,这个其实就是调整layout viewport用滴~。因此,<meta name=”viewport”content=”width=320”>就是设置了layout viewport等于320px。但是,有时候screen.width并不准确,因为像素数过高,比如,Nexus的宽度480px但是Google觉得用device-width的时候480px太多了~于是。。。shrink2/3了。。device-width代表的尺寸缩减到了320px就跟iphone一样。
DPI(dots-per-inch)
设备 | 屏幕尺寸 | 屏幕分辨率 | DPI |
HTC Pyramid | 4.3” | 960*540px | 256 |
Samsung Galaxy S2 | 4.37” | 800*480px | 218 |
iPhone 4 | 3.5” | 960*640px | 326 |
iPad 2 | 9.7” | 1024*768px | 132 |
XOOM | 10.1” | 1280*800px | 160 |
总的来说,屏幕分辨率越高,DPI的值其实是越低的(iPad3是例外)。正因为如此,一般情况下文本和图片缩放太小不能看清楚。举个例子:在96DPI的设备上16px文本显示高度约为2.6/16英寸高,但在256DPI上就是1/16英寸高。因此手机浏览器会放大整个页面,由此引发了图片被发达导致不清晰的情况。
解决方案:
- SVG Method:
SVG可以在Safari和Opera上用作背景图或者图片,但不幸的是,Android 3.0以下不支持,WP7的IE7版本不支持。
- Double-size image method:
使用高分辨率图片去匹配高分辨率设备,然后进行图片缩放。大多数高DPI手机默认放大比数在1.5至1.6之间,所以把图片尺寸双倍后再双倍缩小图片就已经足够保证清晰了。例如:一张宽度32px的图片,你需要存成一张宽度64px的图片然后在页面中把其宽度设成32px。唯一不足的是在低DPI的设备上不能满足,只能借助脚本或者Media Queries.
有关背景图片:
使用CSS3中的background-size 属性,进行背景图片的缩放。但是,Opera Mini和IE(注:wp7 IE9可以支持此属性)。例:
.example {
background: url(‘example.png’) no-repeat top left;
background-size: 32px 32px;
-webkit-background-size: 32px 32px;
}
@Media Queries:
使用Media Queries不仅可以根据H-DPI和L-DPI选择对应的样式, 也可以根据前缀(-webkit和-o)的不同来判断浏览器内核。不过,你得多定义几次。。。例如:
@media screen and (-webkit-min-device-pixel-ratio: 1.5) {…}
@media screen and (-o-min-device-pixel-ratio: 3/2) {…}
不过你有可能喜欢把不同的样式拆分开加载,因此可以写成:
<link rel=”stylesheet” type=”text/css” media=”screen and (max-device-width: 480px)” href=”style.css” />
或者::
@import url(“style2.css”) screen and (orientation:landscape); /*放在css文件开始,此方法非并行加载*/
总结如下:
Android 3.0- 默认浏览器 | Safari | OperaMobile | Opera Mini | Firefox | WP7 IE9 | |
SVG | No | Yes | Yes/Blurry | Yes | Yes | Yes |
Background-Size | Yes | Yes | Yes(显示不完整) | No | Yes | Yes |
关于Android多分辨率
一些Android支持的尺寸概念:
- Screen Size:实际物理尺寸
- Screen density:屏幕的物理面积内的像素数量,通常指dpi(dots-per-inch)
- Resolution:屏幕上物理像素总数。
- Density-independent pixel(dp):一个密度无关的像素,相当于,160dpi屏幕下1个物理像素值。Dp与屏幕像素间转换:
px = dp * (dpi / 160).例,240dpi屏幕上 1dp相当于1.5物理像素值。
总结
- 解决各个分辨率下图片清晰度问题:1)SVG 2)Double-size image +Media Queries
- 关于Media Queries:css的Media Queries不仅能写在css文件里面,也可以使用link或者@import的形式进行并行载入,根据判断条件的不同并行或串行加载不同的css,详情请见附录二。wp7、Android、ios等大三平台对Media Queries的支持都是良好的,只是有个别的判断条件上支持不一样,详情请见附录三。
REF
Dp/Px 转换器:http://labs.skinkers.com/content/android_dp_px_calculator/
@import样式和link样式的区别:
- 加载顺序的差别。当一个页面被加载的时候(就是被浏览者浏览的时候),link引用的CSS会同时被加载,而@import引用的CSS会等到页面全部被下载完再被加载。
- 使用dom控制样式时的差别。当使用javascript控制dom去改变样式的时候,只能使用link标签,因为@import不是dom可以控制的。
因此,个人建议@import只用于附加样式,主体样式依旧使用link形式,且如非必要不要用@import。
Media Queries Supports E.X.
/* Smartphones (portrait and landscape) ———– */
@media only screen and (min-width : 320px) and (max-width : 480px) {/* Styles */}
Support | 默认浏览器 | UC | Opera | |
Android 2.2 | Yes | Yes | Yes | Yes |
IOS 5.1 | Yes | Yes | Yes | Not tested |
WP7 | Yes | Yes | Yes | Not tested |
@media only screen and (orientation:landscape) {/* Styles */}
Support | 默认浏览器 | UC | Opera | |
Android 2.2 | Yes | Yes | Yes | Yes |
IOS 5.1 | Yes | Yes | Yes | Not tested |
WP7 | Yes | No 但是支持(portrait) | Yes | Not tested |
@media only screen and (-webkit-min-device-pixel-ratio : 1.5),only screen and (-o-device-pixel-ratio : 1.5) ,only screen and (min-device-pixel-ratio : 1.5) {/* Styles */}
Support | 默认浏览器 | UC | Opera | |
Android 2.2 | Yes | Yes | Yes | Yes |
IOS 5.1 | Yes | Yes | Yes | Not tested |
WP7 | No | No | No | Not tested |
API:
media_query_list: <media_query> [, <media_query> ]*
media_query: [[only | not]? <media_type> [ and <expression> ]*]
| <expression> [ and <expression> ]*
expression: ( <media_feature> [: <value>]? )
media_type: all | aural | braille | handheld | print |
projection | screen | tty | tv | embossed
media_feature: width | min-width | max-width
| height | min-height | max-height
| device-width | min-device-width | max-device-width
| device-height | min-device-height | max-device-height
| aspect-ratio | min-aspect-ratio | max-aspect-ratio
| device-aspect-ratio | min-device-aspect-ratio | max-device-aspect-ratio
| color | min-color | max-color
| color-index | min-color-index | max-color-index
| monochrome | min-monochrome | max-monochrome
| resolution | min-resolution | max-resolution
| scan | grid