在 CSS 中,1px
到底是多长,为什么是这个长度。百度谷歌搜索很久说法很不一致,最后才发现最标准的还是去看万维网联盟(World Wide Web Consortium,W3C)的CSS 标准和草案(https://www.w3.org/Style/CSS/),总结以下一些概念。
像素
像素是在印刷业和屏幕设备最基础的概念,一切的显示都从像素开始,循序渐进的理解 CSS 像素到底是什么。
物理像素=设备像素(Device Pixel,DP)
物理像素和设备像素
是等同的概念,如下图所示,指的是一个设备屏幕上的有实体的物理像素点,是一个屏幕构成的基本单元。一个像素是屏幕的最小分辨实体,所以屏幕设备的分辨率
也就是dpXSize*dpYSize
(dpXSize
为横向像素数,dpYSize
为纵向像素数)。
屏幕的一个像素又由 RGB(红绿蓝)
三个子像素构成,如下图所示,每个颜色子像素有[0, 2^8-1]
总计 256
种不同强度,三个通道就能组成 2^8×2^8×2^8-1
总计 2^24
种颜色。
每个像素都能表示 2^24
种颜色,所以一个屏幕就可以表示五彩斑斓的图像。
像素密度(Pixels Per Inch,PPI)
像素密度(https://en.wikipedia.org/wiki/Pixel_density)的英文名叫 Pixels Per Inch
,简称 PPI
,顾名思义就是一英寸长度中有多少个物理像素,是一个屏幕的生产出来以后的固有属性。PPI
越大,每英寸内的像素数就越多,画面就越精细。屏幕的长度 length
、分辨率 dpXSzie
或 dpYSize
、像素密度 PPI
有如下换算关系。
dpXSize = lengthX × PPI
dpYSize = lengthY × PPI
注意 length
的单位是英寸 Inch
。所以两个屏幕如果尺寸一样,PPI
大的分辨率一定也大;换句话说,两个屏幕分辨率一样,PPI
大的屏幕尺寸一定小。
参考像素(Reference Pixel,RP)
参考像素
英文名是 Reference Pixel
,简称 RP
,关于参考像素的定义可以参考CSS 工作组的草案(https://drafts.csswg.org/css-values-3/#reference-pixel)。
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).
很关键,翻译一下:
参考像素是一个视觉角度,定义是站在一个手臂远的距离,观察像素密度为 96PPI 的设备中的 1 个像素的视觉角度。以一个名义上的手臂长度是 28 英寸来计算,得到的角度大小是 0.0213°。站在一个手臂远的地方观察,1 个参考像素的长度应相当于 0.26mm(1/96 英寸)。
用下图更简明的解释参考像素,在 0.0213°
的视觉角度下观察,距离为 71cm(28 英寸)
下的 96PPI
设备参考像素长度为 0.26mm
;如果距离为 3.5m(138 英寸)
,参考像素长度就应该等比计算为 1.3mm
。CSS 工作组这样定义的原因是觉得配合其他的标准时,阅读 16 参考像素长度
的文字时体验感最佳。
CSS 像素(px)
有了前置的三个概念就可以介绍到底什么是 CSS 像素
,也就是 px
,CSS 工作组的草案(https://drafts.csswg.org/css-values-3/#px)中是这样写的:
For a CSS device, these dimensions are anchored eitherFor print media at typical viewing distances, the anchor unit should be one of the standard physical units (inches, centimeters, etc). For screen media (including high-resolution devices), low-resolution devices, and devices with unusual viewing distances, it is recommended instead that the anchor unit be the pixel unit. For such devices it is recommended that the pixel unit refer to the whole number of device pixels that best approximates the reference pixel.
- by relating the physical units to their physical measurements, or
- by relating the pixel unit to the reference pixel.
翻译一下:
对于一个 CSS 设备来说,这些维度必须要和下面这两点之一对标锚定对于在典型的阅读距离印刷行业来说,CSS 锚定的单位应该是一个标准的物理单位(英寸、厘米等)。对于媒体屏幕(包括高分辨率屏幕设备)、低分辨率屏幕设备和具有不寻常阅读距离的设备来说,建议将 CSS 单位锚定为物理像素单元。对于这样的设备,物理像素单元指的是最接近
- 衡量设备物理尺寸的物理单位
- 参考像素的像素单位
参考像素
的物理像素数
。
阅读完就很清楚明了,CSS 像素
的长度其实就是最接近
参考像素的物理像素数(整数),是一个相对单位
!同样是在 0.0213°
的视觉角度下观察,距离为 71cm(28 英寸)
下的屏幕设备,观察范围内的物理像素数就是该设备建议的 CSS 像素 1px
的长度。用草案里一张图片来表示,同样是 1px
(1
个 CSS 像素长度),在左面的高分辨率屏幕下 1 个 CSS 像素长度
相当于 4
个物理像素,而右面的普通低分辨率屏幕 1px
就代表 1
个物理像素。
设备独立像素=逻辑像素(Device independent Pixel,DIP)
逻辑像素
又称设备独立像素(Device independent Pixel
),简称 DIP。最简单的理解就是设备无关像素,或者与 PPI
无关的像素。放在前端的 JS 或者 CSS 里理解其实就是 CSS 像素,或者说 CSS 像素是逻辑像素的一种。
设备像素比(Device Pixels Ratio,DPR)
设备像素比
是设备像素数与对应的逻辑像素数的比值,再拿出这张图片,左边的高分屏的 DPR
为 4
,右边普通屏的 DPR
为 1
.
在浏览器中,window.devicePixelRatio
可以拿到当前设备的 DPR
。
视窗(viewport)
以 iPhone11 Pro 举例,设备像素数为 1125×2436
,逻辑像素数为 375×812
,DPR
为 3
。写一个宽高为 200px
、字体大小为 16px
的 div
,结果如下:可以发现,文字几乎看不清,div
所占的比例也很小,说明这里的 px
使用的是设备像素,所以 200px
的宽高 和 16px
的文字 相对屏幕来说很小。给 head 标签中添加一个 meta
元信息标签,让 px
使用逻辑像素。
<meta name="viewport" content="width=device-width" />
结果如下图所示,可以发现,设置一个 width=device-width
,可以让类似 IPhone 这种 DPR
不为 1
的高分屏使用逻辑像素来渲染,显示预想的正确宽高。
几个长度单位
除了常用的 px
和%
,还有 em
、rem
、vw
、vh
、vmax
、vmin
,原文可见CSS 工作组草案(https://drafts.csswg.org/css-values-3/#viewport-relative-lengths)。
px
px
是上文介绍的 CSS 像素
,作为长度单位来说就是:该长度有多少个 CSS 像素
就是多少 px
。一般浏览器默认的字体大小是 16px
。
%
百分比符号的参照规则:
- 普通定位,
%
参照的是父元素的对应属性; position: absolute
,%
参照的是定位后的父元素的对应属性;position: fixed
,%
参照的是viewport
(可视窗口);
后两种很容易理解,毕竟脱离了普通文档流
,肯定以新文档流的父元素做对应。
em
草案原文(https://drafts.csswg.org/css-values-3/#em)如下:
Equal to the computed value of the font-size property of the element on which it is used.
em
单位的大小相当于所在元素的 font-size 属性大小。
详细的说,em
优先参照的自己的字体大小 font-size
、次之参照父元素的字体大小,如果没有就一直继承到 body
。比如父元素设置 font-size: 10px;
,那么 1em=10px
,1.6em
就是 16px
。
rem
草案原文(https://drafts.csswg.org/css-values-3/#rem)如下:
Equal to the computed value of font-size on the root element.If used in the font-size property of the root element, or in a document with no root element, 1rem is equal to the initial value of the font-size property.
rem 单位的大小相当于根元素的 font-size 属性大小。如果如果在根元素的 font-size 属性中使用,或者 document 中没有根元素,1rem 相当于 font-size 初始值的大小。
rem
与 em
的区别就是多了一个 root
,所以 rem
是以根元素 html 的 font-size
为参照,避免了中间多层 em
的混乱。比如根元素 font-size: 16px
,如果想得到 10px
的大小,就用 10/16=0.625rem
。
vw 和 vh
草案原文(https://drafts.csswg.org/css-values-3/#vw)如下:
vw
unit Equal to 1% of the width of the initial containing block.vh
unit Equal to 1% of the height of the initial containing block.
vw
单位大小相当于初始包含块(不含滚动条的视窗)宽度的 1%。vh
单位大小相当于初始包含块(不含滚动条的视窗)高度的 1%。
vw
、vh
就是 viewport width、viewport height 的意思,这两个单位只与视窗高宽有关系,1
单位 vw
或 vh
是视窗高度或宽度的 1%
。
vmax 和 vmin
草案原文(https://drafts.csswg.org/css-values-3/#vmin)如下:
vmin
unit Equal to the smaller of vw or vh.vmax
unit Equal to the larger of vw or vh.
vmin
单位大小相当于vw
和vh
中较小的那个。vmax
单位大小相当于vw
和vh
中较大的那个。
有了 vh
和 vw
的铺垫,vmax
和 vmin
就比较清晰了,vmax = max(vh, vw),vmin = min(vh, vw)
。使用这两个单位有一个很明显的好处,如果给一个块级元素的赋予了 vmax
或 vmin
做单位的宽高,当视窗被缩放时,这个块级元素既会跟随视窗一起缩放,又不会改变块级元素的宽高比导致内容畸形。
引用链接 https://mp.weixin.qq.com/s/R3_aQX0jEgGg7jz2tYAbHQ