CSS 的声明是由属性和值组成的,而值的类型有许多种:
- 数值:长度值 ,用于指定例如元素 width、border-width、font-size 等属性的值;
- 百分比:可以用于指定尺寸或长度,例如取决于父容器的 width、height 或默认的 font-size;
- 颜色:用于指定 background-color、color 等;
- 坐标位置:以屏幕的左上角为坐标原点定位元素的位置,比如常见的 background-position、top、right、bottom 和 left 等属性;
- 函数:用于指定资源路径或背景图片的渐变,比如 url()、linear-gradient() 等;
而还有些值是需要带单位的,比如 width: 100px,这里的 px 就是表示长度的单位,长度单位除了 px 外,比较常用的还有 em、rem、vw/vh 等。那他们有什么区别呢?又应该在什么时候使用它们呢?
px
屏幕分辨率是指在屏幕的横纵方向上的像素点数量,比如分辨率 1920×1080 意味着水平方向含有 1920 个像素数,垂直方向含有 1080 个像素数。
而 px 表示的是 CSS 中的像素,在 CSS 中它是绝对的长度单位,也是最基础的单位,其他长度单位会自动被浏览器换算成 px。但是对于设备而言,它其实又是相对的长度单位,比如宽高都为 2px,在正常的屏幕下,其实就是 4 个像素点,而在设备像素比(devicePixelRatio) 为 2 的 Retina 屏幕下,它就有 16 个像素点。所以屏幕尺寸一致的情况下,屏幕分辨率越高,显示效果就越细腻。
讲到这里,还有一些相关的概念需要理清下:
设备像素(Device pixels)
设备屏幕的物理像素,表示的是屏幕的横纵有多少像素点;和屏幕分辨率是差不多的意思.
设备像素比(DPR)
设备像素比表示1个CSS像素等于几个物理像素。
计算公式:DPR = 物理像素数 / 逻辑像素数;
在浏览器中可以通过window.devicePixelRadio 来获取当前屏幕的DPR.
像素密度(DPI/PPI)
像素密度也叫显示密度或者屏幕密度,缩写为DPI(Dots Per Inch)或者PPI(Pixel Per Inch)。从技术角度说,PPI只存在于计算机显示领域,而DPI至出现于打印或印刷领域.
计算公式:像素密度 = 屏幕对角线的像素尺寸 / 物理尺寸
比如,对于分辨率为 750 * 1334 的 iPhone 6 来说,它的像素密度为:
1 | Math.sqrt(750 * 750 + 1334 * 1334) / 4.7 = 326ppi |
设备独立像素(DIP)
DIP 是特别针对 Android设备而衍生出来的,原因是安卓屏幕的尺寸繁多,因此为了显示能尽量和设备无关,而提出的这个概念。它是基于屏幕密度而计算的,认为当屏幕密度是 160 的时候,px = DIP。
计算公式:dip = px * 160 / dpi
em
em 是 CSS 中的相对长度单位中的一个。居然是相对的,那它到底是相对的谁呢?它有 2 层意思:
- 在 font-size 中使用是相对于父元素的 font-size 大小,比如父元素 font-size: 16px,当给子元素指定 font-size: 2em 的时候,经过计算后它的字体大小会是 32px;
- 在其他属性中使用是相对于自身的字体大小,如 width/height/padding/margin 等;
我们都知道每个浏览器都会给 HTML 根元素 html 设置一个默认的 font-size,而这个值通常是 16px。这也就是为什么 1em = 16px 的原因所在了。
em 在计算的时候是会层层计算的,比如:1
2
3<div>
<p></p>
</div>对于如上一个结构的 HTML,由于根元素 html 的字体大小是 16px,所以 p 标签最终计算出来后的字体大小会是 16 * 2 * 2 = 64px1
2div { font-size: 2em; }
p { font-size: 2em; }
rem
rem(root em) 和 em 一样,也是一个相对长度单位,不过 rem 相对的是 HTML 的根元素 html。
rem 由于是基于 html 的 font-size 来计算,所以通常用于自适应网站或者 H5 中。
比如在做 H5 的时候,前端通常会让 UI 给 750px 宽的设计图,而在开发的时候可以基于 iPhone X 的尺寸 375px * 812px 来写页面,这样一来的话,就可以用下面的 JS 依据当前页面的视口宽度自动计算出根元素 html 的基准 font-size 是多少。
vw/vh
vw 和 vh 分别是相对于屏幕视口宽度和高度而言的长度单位:
1vw = 视口宽度均分成 100 份中 1 份的长度;
1vh = 视口高度均分成 100 份中 1 份的长度;
在 JS 中 100vw = window.innerWidth,100vh = window.innerHeight。
vw/vh 的出现使得多了一种写自适应布局的方案,开发者不再局限于 rem 了
相对视口的单位,除了 vw/vh 外,还有 vmin 和 vmax:
vmin:取 vw 和 vh 中值较小的;
vmax:取 vw 和 vh 中值较大的;