CSS 单位

PX

px 是一个绝对单位,不相对于谁,只受平台 dpi 影响。cmpt 之类的也都是绝对长度,但与 px 这个抽象单位不同的是它们都是物理单位,1pt 则是 1/72 英寸,而 1 英寸换算到公制是 2.54cm,在 CSS 中所有的物理单位会直接映射到像素,在 96dpi1in = 2.54cm = 96px 1cm = 37.8px

EM

em 是一个相对单位,相对于当前元素的 font-size(如果当前元素没有 font-size 或者 font-size 是相对单位,则先继承父辈的字号,再计算 em)。也可以说,在 font-size 中使用是相对于父元素的字体大小,在其他属性中使用是相对于自身的字体大小。不管怎么样,要想计算 em 的大小,要先确定当前元素具体的 font-size

1
2
3
<div style="font-size: 12px; line-height: 1.5em">
<span style="display: inline-block; width: 4em; font-size: 3em;">Test</span>
</div>

上面例子中,span 先继承父元素 font-size,再计算自身 font-size,即 3em * 12px = 36px,width 为 4 * 36px = 144px。另外,对于相对单位属性的继承,要在父辈元素先计算为具体值,再继承,divline-height1.5em * 12px = 18px,所以 spanline-height18px,而不是直接继承 1.5em

由于 em 相对于当前元素的字号大小,而且字号会继承,这导致不能统一管理基础变量,且依赖追溯复杂,不适合在整个页面中使用,只适用于做局部缩放的场景。

历史上,因为 IE 不支持 px 为单位的缩放,故使用 em 来做缩放。Richard RutterHow to size text using emsHow to Size Text in CSS 中做过详细的介绍。

1
window.getComputedStyle(document.querySelector(':root'), null).fontSize; // 16px,Chrome 上最小支持的字号为 12px

<html>font-size 为基准,浏览器默认的字号为 16px,换算为 em 即 1em = 16px12px = 0.75em10px = 0.625em,为了方便 font-size 的换算,可将 html 字号设为 font-size: 62.5%(即 16px * 62.5% = 10px),或者直接 font-size: 10px,这样 1em = 10px1.2em = 12px1.4em = 14px

1
2
3
4
5
6
7
8
// 10 ÷ 16 × 100% = 62.5%
body {font-size: 62.5%;}

// body>h1, 2.4em × 10 = 24px
h1 {font-size: 2.4em;}

// body>p, 1.4em × 10 = 14px
p {font-size: 1.4em;}

随着浏览器的更新换代,这种做法早已被淹没在历史尘埃中。

Percent

一般情况下 % 相对于包含块(containing block),在应用于字体大小时,相对于父字体大小。

包含块的确定:

1
2
3
* 对于普通定位元素就是父元素
* 对于 position: absolute 的元素是相对于已定位的父元素(offset parent)
* 对于 position: fixed 的元素是相对于 ViewPort(可视窗口)

需要注意的是 paddingmargin 如果设置了百分比,会发现左右和预期一样,用的父元素宽度的百分比,但是上下用的也是宽度百分比,而不是想象中的高度的百分比。另外 percent 在被后代元素继承时继承的是百分比计算后的值,而不是原百分比,比如 line-height 120%1.2 在被继承时。

REM

rem 相对于根元素 font-size 的单位。引入它是为了解决 em 依赖追溯困难,计算复杂的问题。而 rem 是相对于根元素 <html>,依赖简单,只需要在根元素确定一个参考值。

1
2
3
4
5
6
7
8
// 10 ÷ 16 × 100% = 62.5%
html {font-size: 62.5%;}

// 1.4 × 10px = 14px
body {font-size: 1.4rem;}

// 2.4 × 10px = 24px
h1 {font-size: 2.4rem;}

虽然 emrem 相对于 font-size,但是并不单单只能应用于 font-size。另外,所有的 emrempercent 渲染的时候,都会被转为 px,因为 px 是计算机矢量图渲染成像的原理。

rem 常用来做移动端适配。

VW、VH

vw 是 CSS3 引入的单位,相对于视口的宽度,视口被均分为 100 单位的 vw1vw = 1% 窗口宽度。vh 同理。常用来配合 rem 做移动端适配。

总结

各个单位都有各自的优缺点,取决于场景,不能脱离场景谈应用。例如 emremvhvwpercent 这些相对单位,比较适合做尺寸联动适配。