Android手机上关于viewport的理解

Alexlee 2013-08-18

一.Android默认的viewport(即网页未设置viewport元标签的时候)(windows.innerWidth)

在网页未加载完成时,值为320,一旦页面加载完成,该值会发生改变,android_2.x的值为800,android_4.x的值为980,用以适配一般的web网页。

二.Android的手机分辨率的获取

使用window.screen获取,虽然window.screen不是w3c标准,但是绝大部分浏览器均支持。

经测试,在android2.2和2.3上的自带浏览器,该值(window.screen.width和window.screen.height)获取的是错误的,和浏览器的viewport的宽高一样(有人认为这是android2.2和2.3的bug,链接如下:https://code.google.com/p/android/issues/detail?id=12455),在android2.1和4.0以上的系统,均显示正确的分辨率。

三.设备像素比(window.devicePixelRatio)

一般window.devicePixelRatio的值为0.75,1,1.5,2,2.25,3等。苹果规定window.devicePixelRatio的值为1或2,来区分普通屏幕和视网膜屏,但是谷歌拓展该定义,用以适配更多的尺寸的屏幕。

四.viewport元标签

主要讲width和target-densitydpi两个属性:

1. width 

设置viewport的宽度,iphone下有效(iphone读取后自动计算target-densitydpi),android_4.0以上有效(若不设置target-densitydpi;设置target-densitydpi后,则以target-densitydpi为准)

2. target-densitydpi

Android浏览器所需要的,因为Android硬件设备标准不一, 其中同样物理尺寸的屏幕,可能因为dpi的不同而具有不同的分辨率。

target-densitydpi可以设定的值(device-dpi|指定的具体的dpi的值),target-densitydpi有三个常量:high-dpi(240),medium-dpi(160),low-dpi(120),分别对应分辨率为480*800,320*480,240*320。

具体计算公式:

    target-densitydpi = UI-width / device-width * window.devicePixelRatio * 160

(应用的公式原理是设备的宽度的物理像素的计算)

案例:

如果设置viewport为<meta name="viewport" content="target-densitydpi=medium-dpi, width=320, user-scalable=no" />,页面放置一个宽为320px的图片时,在720*1280的手机上看到的效果是有40px的宽度上的空白。这是因为该手机的真实dpi的值不是默认的medium-dpi(160),而是142.2,根据上面公式,计算出的页面宽度为720/2=360,所以会有40px的空白。

此时,如果需要将320px的图片无缩放的铺满网页的宽度,可以将target-densitydpi的值通过js按上述公式计算后重新设置即可。(注:Android2.2和2.3上无法正确设置,原因见第二条,设备的分辨率宽度获取不正确,可以采取medium-dpi这个默认值)。

总结

1.若手机网页需要定死宽度,比如320或480等,需要设置viewport的target-densitydpi,最好是根据上条公式计算出(若是Android2.2和2.3,则可以给出默认值medium-dpi),可以适配绝大多数的手机网页,包括720p和1080p等(除非是Android2.2或2.3系统的手机,且分辨率又是比较奇葩的(不是320,480等),这样的手机毕竟很少,如果需要完美适配页面宽度,只能根据ua通过服务器查询该机型的分辨率,然后计算)

2.手机页面不要使用绝对宽度,可以通过百分比设置,一方面以防出现viewport设置不正确(1中的例外情况)后,页面变形;另一方面方便以后修改(只需修改viewport中的参数即可)

3.若手机网页需要按照设备宽度,设置viewport的target-densitydpi为device-dpi,页面可采用响应式布局,或media queries等技术。

 

相关推荐