带你走进“像素”的世界

前言

一位漂亮的UI小姐姐,给了一个高60px、宽112px的确定按钮,和一个宽高都是60px的返回按钮,其中返回按钮由端上实现,确定按钮由H5实现。于是大家都按照设计稿写好了样式,联调的时候,pc没有问题,开心;ios没有问题,开心极了;然而安卓在安卓机上拉胯了!!
在这里插入图片描述
于是开始排坑之路。

像素(pixel)

像素(pixel)是影像显示的基本单位,它是一个取样单位,一般情况像素采用点或者方块显示。一般屏幕上每个像素采用RGB色域(红、绿、蓝),印刷机采用CMYK色域(青、品红、黄、黑)。详情可以参考wiki百科

物理像素(physical pixel)

物理像素是显示屏中最小的物理显示单位,它是一个纯硬件指标,反映了显示屏内led灯的数量,在出厂时就已经固定。比如我把屏幕对半折,那么它的物理像素也只有一半。每个像素点具有自己的颜色值和亮度。
在这里插入图片描述
现代液晶屏幕按设计有一个原始分辨率,它代表像素和三元素组之间的完美匹配。(阴极射线管也是用红-绿-蓝荧光三元素组,但是它们和影像像素并不重合,因此和像素无法比较)

非原始分辨率必须通过在液晶屏幕上拟合重新取样来实现,要使用插值算法。这经常会使屏幕看起来破碎或模糊。例如,原始分辨率为1280×1024的显示器在分辨率为1280×1024时看起来最好,也可以通过用几个物理三元素组来表示一个像素以显示800×600,但可能无法完全显示1600×1200的分辨率,因为物理三元素组不够。

CSS像素(CSS pixel)

在CSS规范中,长度单位可以分为绝对(absolute)单位和相对(relative)单位两类。其中CSS像素px是相对单位。
在这里插入图片描述

由于不同的物理设备的物理像素的大小是不一样的,所以css认为浏览器应该对css中的像素进行调节,使得浏览器中 1css像素的大小在不同物理设备上看上去大小总是差不多 ,目的是为了保证阅读体验一致。css规范中使用“参考像素”来进行换算。

参考像素

根据W3C文档中的描述:

The reference pixel is the visual angle of one pixel on a device with a pixel density of 96dpi and a distance from the reader of an arm’s length. For a nominal arm’s length of 28 inches, the visual angle is therefore about 0.0213 degrees. For reading at arm’s length, 1px thus corresponds to about 0.26 mm (1/96 inch).

在这里插入图片描述

参考像素是一个视觉角度。假设当前设备的像素密度96dpi(即一英寸96个点),当用户从距离一胳膊远的地方看设备,眼睛与其中两个相邻点之间距离形成的夹角度数就是参考像素。常人的胳膊长度约为28英寸,其可视角度约为(1/96)in / (28in * 2 * PI / 360deg) = 0.0213度,此时1px大约是0.26mm。当观看距离越远时,参考像素就越大(指角度对应在屏幕上的尺寸变大)。

虽然规范这么定义,但明显不好理解,所以每个浏览器具体实现的时候,都是根据“设备像素”直接换算的。

举一个🌰

直观感受一下css像素的相对性。写一个如下的样式:

.box {
    width: 100px;
    height: 100px;
    background-color: aqua;
}

在这里插入图片描述

此时修改页面,放大200%。
在这里插入图片描述

可以看到方块变大了一倍,但是宽高样式还是100px。
在这里插入图片描述

这是因为默认情况下,一个CSS像素等于一个物理像素。将浏览器放大200%后,就是让一个1CSS像素等于2物理像素,即使用22的物理像素表示一个11的CSS像素。在高PPI的设备上,一个CSS像素默认等于多个物理像素的尺寸。

像素密度(Dots Per Inch,Pixel Per Inch )

像素密度也叫显示密度或者屏幕密度,缩写为DPI(Dots Per Inch)或者PPI(Pixel Per Inch),含义相同。细微差异如下:

ppi和dpi(每英寸点数)。从技术角度说,“像素”(p)只存在于计算机显示领域,而“点”(d)只出现于打印或印刷领域。

经常看到相同尺寸的屏幕像素尺寸却不同,也就是DPI的差异,比如4.7英寸的iPhone6像素尺寸为750x1334px,而4.7英寸的HTC One像素尺寸为1080x1920px

像素密度很容易算出来:
P P I = d p d i = w p 2 + h p 2 d i PPI ={dp\over{di} }={\sqrt{wp^2+hp^2}\over di} PPI=didp=diwp2+hp2
其中:

  • dp为屏幕对角线的分辨率
  • di为屏幕对角线的长度(单位为英寸)
  • wp为屏幕横向分辨率
  • hp为屏幕纵向分辨率

以iPhone6为例:

// 屏幕对角线的像素尺寸 / 物理尺寸(inch)
Math.sqrt(750*750 + 1334*1334) / 4.7 = 326ppi

常见像素密度缩写:

缩写名称PPI
TVDPIMedium High density≈160–213
HDPI or HiDPIHigh density≈213–240
XHDPIeXtra High density≈240–320
XXHDPIeXtra eXtra High density≈320–480
XXXHDPIeXtra eXtra eXtra High density≈480–640

设备独立像素(device independent pixel)

设备独立像素(也叫密度无关像素),可以认为是计算机坐标系统中得一个点,这个点代表一个可以由程序使用的虚拟像素(比如: css像素),然后由相关系统转换为物理像素。

如果设备独立像素作为单位,在Android中缩写为DIP(Device Independent Pixels)或者DP(Density-independent Pixels),含义一致。

Android设备的特点是屏幕尺寸很多,因此为了显示能尽量和设备无关,dip参照的density是160。计算公式为:

// 当屏幕密度为160(单位是ppi或者dpi,一个意思)时,px === dip
px = dip * density / 160 
// 所以
dip = px * 160 / dpi

当然,这两个式子都只适用于Android设备,这个dip拿到其它地方去没什么意义。

一般情况可以认为下面等式成立:

设备独立像素 = CSS像素 = 逻辑像素(都具备相对性)

物理像素和设备独立像素之间的关系就是设备像素比。

设备像素比(device pixels ratio)

Device pixel ratio, the ratio between physical pixels and logical pixels used by cascading style sheets (CSS): other names for it are “CSS Pixel Ratio” and “dppx”

从定义中可以知道,DPR就是物理像素 (physical pixels) 和设备无关像素 (device-independent pixels (dips)) 的比例。公式表示就是:window.devicePixelRatio = physical pixels / dips

通过devicePixelRatio,就可以知道一个设备独立像素代表多少个物理像素。例如,在Retina屏上,devicePixelRatio的值为2,也就是说1个css像素相当于2个物理像素。但是早期devicePixelRato输出的值不太准确(目前可以放心使用),具体的情况可以看下PPK大神的文章

  • IE以及FireFox压根不支持。可能接下来的版本会支持。
  • Opera桌面浏览器时,即使是视网膜设备,返回的值也是1而不是2。不过,这个bug在后续的版本中会修复的。
  • Opera Mobile 10不支持,不过Opera Mobile 12正确支持。
  • UC总是显示1,不过其viewport属性有些让人费解。
  • 只有最近的Chrome浏览器才能正确实现该属性。Chrome19返回不准确的1, Chrome22可以正确返回2。
  • MeeGo WebKit (Nokia N9/N950)就吓人了:当你应用了meta viewport时候(类似<meta name="viewport" content="width=device-width">),值会从1变成1.5!
    在css中,可以通过-webkit-device-pixel-ratio,-webkit-min-device-pixel-ratio和 -webkit-max-device-pixel-ratio进行媒体查询,对不同dpr的设备,做一些样式适配(这里只针对webkit内核的浏览器和webview)。

viewport像素

ppk大神对于移动设备上的viewport有着非常多的研究(第一篇第二篇第三篇),有兴趣的同学可以去看一下。ppk认为,移动设备上有三个viewport。

layout viewport(布局视口)

如果把移动设备上浏览器的可视区域设为viewport的话,某些网站就会因为viewport太窄而显示错乱,所以这些浏览器就决定默认情况下把viewport设为一个较宽的值,比如980px,这样的话即使是那些为桌面设计的网站也能在移动浏览器上正常显示了。ppk把这个浏览器默认的viewport叫做 layout viewport。这个layout viewport的宽度可以通过 document.documentElement.clientWidth 来获取。
在这里插入图片描述

visual viewport(视觉视口)

因为 layout viewport 的宽度是大于浏览器可视区域的宽度的,所以我们还需要一个viewport来代表 浏览器可视区域的大小,ppk把这个viewport叫做 visual viewport。visual viewport的宽度可以通过window.innerWidth 来获取,但在Android 2, Oprea mini 和 UC 8中无法正确获取。
在这里插入图片描述

Ideal viewport(理想视口)

但浏览器觉得还不够,因为现在越来越多的网站都会为移动设备进行单独的设计,所以必须还要有一个能完美适配移动设备的viewport。所谓的完美适配指的是,首先不需要用户缩放和横向滚动条就能正常的查看网站的所有内容;第二,显示的文字的大小是合适,比如一段14px大小的文字,不会因为在一个高密度像素的屏幕里显示得太小而无法看清,理想的情况是这段14px的文字无论是在何种密度屏幕,何种分辨率下,显示出来的大小都是差不多的。当然,不只是文字,其他元素像图片什么的也是这个道理。ppk把这个viewport叫做 ideal viewport。此时Ideal viewport像素可以理解为设备独立像素。
在这里插入图片描述
在这里插入图片描述

小结

其中的ideal viewport是最适合移动设备的viewport,ideal viewport的宽度等于移动设备的屏幕宽度,只要在css中把某一元素的宽度设为ideal viewport的宽度(单位用px),那么这个元素的宽度就是设备屏幕的宽度了,也就是宽度为100%的效果。ideal viewport 的意义在于,无论在何种分辨率的屏幕下,那些针对ideal viewport 而设计的网站,不需要用户手动缩放,也不需要出现横向滚动条,都可以完美的呈现给用户。

其他名词

看一张从网上淘来的图片:
在这里插入图片描述

渲染像素(render pixel)

渲染像素是在系统内部对物理像素的分配进行再一次的调整,在pc上,渲染像素其实就是设置里边的分辨率。对于显示设备,系统为显示设备提供渲染尺寸,由显示设备的“缩放引擎”(带存储器阵列的数字视频处理器)处理。这种“缩放引擎”一般内部有一系列的合理分辨率和一个推荐分辨率。一般推荐分辨率就是最大渲染像素,也是设备的物理分辨率(为了最佳表现)。这是一个软硬件(偏硬)结合的缩放方案。由于部分设备不能设置渲染像素,可直接等同于物理像素

逻辑像素/点(device point / device pixel / point )

逻辑像素/点是为了调和距离不一样导致的差异,将所有设备根据距离,透视缩放到一个相等水平的观看距离之后得到的尺寸,是一个抽象的概念,这个单位就是ios开发的pt,安卓开发的dp,前端的css px。对于pc,包括win(8+) linux,mac,由各自系统的或者对应软件(比如webview内部)提供的图像界面处理引擎处理进行缩放。

相关文档

设备像素比devicePixelRatio简单介绍 « 张鑫旭-鑫空间-鑫生活
Android dp 和 CSS px
https://www.zhihu.com/question/313971223/answer/628236155
https://www.zcoldwater.com/articles/2019/12/10/1575969868852.html
The Ultimate Guide To iPhone Resolutions
CSS像素、物理像素、逻辑像素、设备像素比、PPI、Viewport
移动前端开发之viewport的深入理解 - 无双 - 博客园
【CSS】绝对单位和相对单位
你真的了解css像素嘛?
完全理解px,dpr,dpi,dip | 黯羽轻扬

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值