css中的相对单位与绝对相位
传统pc端网页设计中,设计师给出的视觉元素大小的衡量单位通常是以css中的px为单位的。我们也从来不去关心一px到底有多长,只要按照设计师给出的px大小编写css代码即可。所以很多前端开发认为px是绝对单位,甚至很多css书籍中也简单的告诉我们px是绝对em、ex、单位百分比是相对单位。
而实际上除了pt之外其他都是相对单位,关于pt这个单位我除了在《css权威指南》种有见过外,其他css书籍从未提到。pt在css单位中属于真正的绝对对单位,1pt = 1/72(inch),inch及英寸,而1英寸等于2.54厘米。
那么px到底是什么?
px实际是pixel(像素)的缩写,根据 维基百科的解释,它是图像显示的基本单元,既不是一个确定的物理量,也不是一个点或者小方块,而是一个抽象概念。所以在谈论像素时一定要清楚它的上下文!一定要清楚它的上下文!一定要清楚它的上下文!
不同的设备,图像基本采样单元是不同的,显示器上的物理像素等于显示器的点距,而打印机的物理像素等于打印机的墨点。而衡量点距大小和打印机墨点大小的单位分别称为ppi和dpi:
ppi:每英寸多少像素数,放到显示器上说的是每英寸多少物理像素及显示器设备的点距。
dpi:每英寸多少点。
关于打印机的点距我们不去关心,只要知道 当用于描述显示器设备时ppi与dpi是同一个概念 。
CSS像素的真正含义
由于不同的物理设备的物理像素的大小是不一样的,所以css认为浏览器应该对css中的像素进行调节,使得浏览器中 1css像素的大小在不同物理设备上看上去大小总是差不多 ,目的是为了保证阅读体验一致。为了达到这一点浏览器可以直接按照设备的物理像素大小进行换算,而css规范中使用"参考像素"来进行换算。
1参考像素即为从一臂之遥看解析度为96DPI的设备输出(即1英寸96点)时,1点(即1/96英寸)的视角。它并不是1/96英寸长度,而是从一臂之遥的距离处看解析度为96dpi的设备输出一单位(即1/96英寸)时视线与水平线的夹角。通常认为常人臂长为28英寸,所以它的视角是(1/96)in / (28in * 2 * PI / 360deg) = 0.0213度。
由于css像素是一个视角单位,所以在真正实现时,为了方便基本都是根据设备像素换算的。浏览器根据硬件设备能够直接获取css像素
设计师的设计稿
CSS网页开发的目的就是还原设计师的设计稿,pc时代的前端开发者不需要去了解CSS像素的来龙去脉,只需要按照设计师的标注用css还原即可,而且设计稿的长度单位跟设备的显示单位一致。
然而随着移动时代的发展,不同尺寸不同设备分辨率,相同尺寸下不同分辨率。为了在各式各样的手机屏幕上有一致的视觉,甚至是同一份设计稿要同时在native和移动web上使用,设计稿需要定一个设计标准,即设计稿的大小和视觉元素的长度单位,然后在各个设备上做适配。
dpi、ppi、dip、分辨率、屏幕尺寸、设备像素、css像素、设备像素比
dpi每英寸点数,ppi每英寸像素数,上文已经说过用于显示设备时这俩都是只每英寸设备像素数目。
dip是安卓中的单位,它的含义是设备无关像素,简写为dp。
分辨率是横纵两个方向上设备像素数目,如iphone7+是1080x1920
屏幕尺寸是指屏幕对角线的长度,一般说的多少寸屏幕就是指的对角线长度
设备像素这里可以指手机屏幕的长度单位,一般用px表示
css像素是上文提到的浏览器中使用的长度单位,在css中也用px表示。
设备像素(dpr)比是指在移动开发中一css像素占用多少设备像素,如2代表1css像素用2x2个设备像素来绘制。
同一个图标在不同的手机屏幕上显示出来的效果是不同的。图片显示大小是由什么决定的呢,屏幕尺寸?上图第1和第2个屏都是4.3英寸。像素数?第2和第3个屏都是720x1280的像素。最后我们找到了点密度(density),也就是像素数和屏幕尺寸的比值。density是每单位长度容纳的像素数量,一般用像素/英寸,也就是Pixel per inch(ppi)。【本段落及图片出自第二篇参考资料】
ppi的计算方式如下:
可以看到高清屏需要更大的图片才能得到同样的显示效果,ppi和图片的设备像素关系如下:
px1/px2 = ppi1/ppi2,所以
px2 = px1 * (ppi2 / ppi1),而安卓中选定的基础值是160ppi,所以
px2 = px1 * (ppi2 / 160),ppi1的基础已经选定,这里开始引入一个新单位dp,安卓中规定,在160ppi下1dp = 1px,所以
px2 = dp * (ppi2 / 160)
所以设计师只需要根据160ppi的显示屏出设计稿,安卓会根据当前手机屏幕的ppi值来自动缩放。
之说以详细总结dp的知识,是因为我经常拿到的设计稿是以dp为单位的。。。。
前面提到过,css像素的目的是为了保持同一css像素在不同设备下的大小基本相同,由于设备像素大小并不固定,这就是说1css像素在不同屏幕下会使用不同数量的设备像素来绘制
而css像素与设备像素的换算关系是上文提到的设备像素比有关,而设备像素比与ppi相关,一般是ppi/160的整数倍:
1dp定义为屏幕密度值为160ppi时的1px,即,在mdpi时,1dp = 1px。 以mdpi为标准,这些屏幕的密度值比为:ldpi : mdpi : hdpi : xhdpi : xxhdpi = 0.75 : 1 : 1.5 : 2 : 3;
移动web端的适配
由于css像素的目的是为了在不同显示器上1css像素大小基本相同,这给我们移动web开发带来了不少困难。我们的目的是还原设计师的设计稿,而设计师通常会选定一个标准屏幕大小来做标注。 移动web适配的主要工作把这幅设计稿缩放到任意大小的屏幕中,所以在不同的屏幕下,同一个元素的css像素是不一样的 。而且如果你的设计稿的标注单位是dp,那就需要先把dp转换成对应的设备px,然后把设备px最终转换成css px。
上图中设计稿是在iphone7+的屏幕分辨率1080x1920下给出的设计稿。
如果我们的viewport如下设置:
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no">
通过上文的讲解在 http://screensiz.es/phone查询到在iphone7+的ppi下,1dp=3px。而后根据屏幕设备比(dpr),确定css像素。
css像素 = 标注像素/dpr
得到在iphone7+下的css像素,对于其他屏幕下的css像素计算公式:
px2/css = dpr2 / dpr1
我们可以通过判断window.devicePixelRadio来加载不同的css样式。
为什么不适用rem?
如果你的网页完全由自己开发掌控,那么可以使用淘宝的解决方案,利用rem来做适配( 使用Flexible实现手淘H5页面的终端适配)。但如果你的东西要提供给开发者或第三方集成,那么还是老实的使用px吧。
DPI、PPI、DP、PX 的详细计算方法及算法来源是什么?
https://zh.wikipedia.org/wiki/%E6%AF%8F%E8%8B%B1%E5%AF%B8%E5%83%8F%E7%B4%A0