1.页面大小
有没有遇到过一个情况?在iphone 4机器上开发时,明明分辨率是960*640,我们写一个320px的容器,竟然占满了屏幕宽;显示一张100*100的图片,会出现模糊失真,必须把图片的宽高都缩小一倍,变成50*50才会正常。
导致上面情况的原因是什么呢?这和新的度量单位DPI有关
(1)PPI/DPI
PPI,有时也叫DPI,所表示的是每英寸所拥有的像素数目,数值越高,即代表显示屏能够以越高的密度显示图像。计算PPI的方法我借鉴了一些文章的图片。
我们需要首先算出手机屏幕的对角线等效像素,然后处以对角线(我们平常所说的手机屏幕尺寸就是说的手机屏幕对角线的长度),就可以得到PPI了。
(2)px和像素的区别
首先我们需要明确一点,等值的CSS里面的px在手机屏幕上占多大的位置,这不是固定的,还要取决于屏幕的DPI。因为手机会根据DPI,对页面进行自动缩放来协调屏幕像素和尺寸之间的显示效果。我们计算PPI就是为了知道一部手机设备是属于哪个密度区间的,因为不同的密度区间,对应着不同的默认缩放比例,这是一个很重要的概念。
图1
可以看到,iphone 4的DPI是330,属于xhdpi,默认缩放比例为2,这意味着1个css px实际上是显示了两个像素点,那么一个320px的容器占满屏幕的情况就可以理解了,而图片的显示,因为在photoshop内表示图片的100*100像素是和屏幕像素对应的,那么在页面内使用100px大小显示图片,情况就相当于在photoshop内将图片放大一倍的效果,模糊、失真是肯定的。
这个缩放比例影响了什么?它让我们开发的时候,考虑的页面大小并非简单的等于屏幕分辨率,而应该是:
页面大小 = 分辨率/DPI
举些例子:
IPHONE 4 [640*960]/2 = [320*480]
HTC G11 [480*800]/1.5 = [320*533]
用viewport让页面保持1:1输出
1
|
< meta name = "viewport" content = "width=device-width, user-scalable=no ,target-densitydpi=device-dpi ,initial-scale= 0.5" /> |
重点关注target-densitydpi属性,这个属性可以改变设备的默认缩放。medium-dpi是target-densitydpi的默认值,如果我们显式定义target-densitydpi=device-dpi,那么设备就会按照真实的dpi来渲染页面。
我们采用 target-densitydpi=device-dpi,这样一来,手机设备就会按照真实的像素数目来渲染,用专业的话来说,就是1 CSS px = 1像素。但是IOS对target-densitydpi不支持,所以我们只能设置 initial-scale=0.5 直接让iphone页面缩小一半。
这样对于视网膜屏的iphone,页面整好是xhdpi[960*640],旧版的iphone由原来的[480*320]放大为[960*640],布局效果上没有变化,只是图片流量会有所浪费因为原本为高清屏准备的图片被缩小了显示;其它android机器也不会再缩放。
获取当前设备分辨率:
<!DOCTYPE > <html> <head> <meta name="viewport" content="width=device-width, user-scalable=no ,target-densitydpi=device-dpi ,initial-scale= 0.5"/> <meta http-equiv="content-type" content="text/html; charset=UTF-8" /> <script type="text/javascript" src="http://code.jquery.com/jquery-1.9.0.min.js"></script> <style> body,html{ margin:0;padding: 0; } </style> </head> <body> <div style="width:640px;height:960px;background:red;"> <font style="font-size:24px;">屏幕物理像素宽/高/设备像素比/缩放</font> </div> <div> <img src="back_btn.png"> </div> <script type="text/javascript"> $(document).ready(function(){ var initial_scale = 1/window.devicePixelRatio; alert("宽" +$(window).width() + " /高" + $(window).height() + " / " +window.devicePixelRatio + " / " + initial_scale); }) </script> </body> </html>
window.devicePixelRatio是设备上物理像素和设备独立像素(device-independent pixels (dips))的比例。
公式表示就是:window.devicePixelRatio = 物理像素 / dips
所有非视网膜屏幕的iphone在垂直的时候,宽度为320物理像素。当你使用<meta name="viewport" content="width=device-width">
的时候,会设置视窗布局宽度(不同于视觉区域宽度,不放大显示情况下,两者大小一致,见下图)为320px, 于是,页面很自然地覆盖在屏幕上。
这样,非视网膜屏幕的iphone上,屏幕物理像素320像素,独立像素也是320像素,因此,window.devicePixelRatio
等于1
.
而对于视网膜屏幕的iphone,如iphone4s, 纵向显示的时候,屏幕物理像素640像素。同样,当用户设置<meta name="viewport" content="width=device-width">
的时候,其视区宽度并不是640像素,而是320像素,这是为了有更好的阅读体验 – 更合适的文字大小。
这样,在视网膜屏幕的iphone上,屏幕物理像素640像素,独立像素还是320像素,因此,window.devicePixelRatio
等于2
.