说一说CSS里面的数值单位
写于2016年05月03日

css单位分为绝对单位(absolute units)和相对单位(relative units)。绝对单位就是不受其他数值的影响,在任何地方使用相同的值都会出现相同的效果。而相对单位就是会受其他元素影响,在不同的地方使用相同的值可能效果也会不同。看下下面这个表

单位 类型 描述
px 绝对单位 像素
mm 绝对单位 毫米
cm 绝对单位 厘米
in 绝对单位 英寸
pt 绝对单位 1英寸的72分之1
pc 绝对单位 1英寸的6分之1
em 相对单位 当前元素字体大小的倍数
ex 相对单位 小写字母x的高度的倍数
ch 相对单位 数字0的宽度的整倍数
rem 相对单位 根元素(html)字体大小的倍数
vw 相对单位 可视窗口宽度的1/100
vh 相对单位 可视窗口高度的1/100

需要注意的是,1in的长度最后在显示器上的效果不一定真的是1英寸,在一些高分辨的设备上可能会比较精确(比如激光打印机),但在一些低分辨率上就不一定这样精确了。css对此明确没有要求。

ptpc这两个单位是从印刷技术那里继承下来的,打印机经常使用这两个或者类似的单位。在css里面已经没有理由使用这两个单位了。不过当你的样式是用来准备打印的,需要精确控制打印内容尺寸的大小的时候,也请使用ptcm这些单位。

单位换算

pxmmcm等现实中的单位是没有绝对大小关系的。但是这些现实中的单位是可以互相转换的,关系如下:

1in = 2.54cm = 25.4mm = 72pt = 6pc

不过实际我们也很少用到这些单位。

关于em

em 这个单位最常见的错误就是会认为是以父元素的字体大小为基准。但实际上它是相对于当前元素的字体大小来计算的,我们之所以会错误的以为em是相对于父元素字体的大小,完全是因为font-size的继承效果。下面我们来演示一下吧。

em单位如何转换成具体值的

上面的 child 的实际大小是 30px,是如何计算出来的呢?这里.parent的大小是16px,因此.wrap元素由于继承,它原本的大小是16px,由于它设置font-size: 1.5em,所以它的最终大小是 16 * 1.5 = 24px.child因此继承到的大小是24px,由于它设置font-size: 1.25em,所以它的最终大小是 24 * 1.25 = 30px。所以除非你通过绝对大小单位比如pxvw等重新设置了字体大小,否则em的倍数是会一层一层的累积的。我们再来看另外一个例子:

这里我们计算了 padding 的大小,这里能提现出 em 是以当前元素的 font-size 为参考的,这里 .childfont-size 计算后的结果由上面可知是 30px。然后计算 padding 的时候就是 30 * 1.25 = 37.5px

由上面我们可以知道,em为单位的最终大小会受到每一个祖先元素的影响(如果中间某一祖先元素使用了pxvw等绝对大小的单位,则之前的祖先元素的影响就能忽略,em的计算会重新从这里开始),所以在使用 em 的时候一定要格外清楚祖先元素的设置情况。

rem和em该如何选择?

em可以在一个特定的区域里面使用,比如说导航栏,通过把边界宽度设置为em单位使得调整字体的时候能够保证视觉上能够等比缩放。因为视觉上是参考一个较小区域内的元素,所以即使祖先元素会影响其大小,但是在实际设计的时候并不会干扰。

使用rem能够确保整个网站的整体布局。如果没有显示地设置html元素的字体大小,那么将会使用浏览器设置的字体大小作为html元素的字体大小。不建议显示地将html的文字大小设置为绝对的值,因为用户就无法改变网页字体的大小。而且,如果你真的需要改变html字体大小,最好使用em,这样用户也能自己改变网页大小。
有些用户的习惯于看大号的字体,或者说小字体看不清(比如我妈)。所以保证网页字体可以由用户调整是非常重要的。然后网页中尽量使用rem单位来设置每一个地方的尺寸。在使用媒体查询的时候,也使用rem为单位,让布局跟随字体大小改变而不是像素大小改变。

vh和vw

在很多地方,我们经常需要元素的大小随着浏览器窗口大小调整。我们平常会使用百分比这个单位。但是问题在于,百分比这个单位是相对于父元素的大小来设置的。对于块级元素来说,如果不设置宽度,默认就是占满父元素的空间,这没什么大问题。但是高度就不同了,如果你没有设置高度,那么默认是根据内容多少来确定的。所以当你需要高度随着浏览器窗口的高度变化时,问题就有点棘手了,要么你用JS获取当前浏览器的高度,然后通过绝对大小来更改,要么就一层一层地给每一个元素设置 height: 100%; 来保证最终的那个元素得到高度参考是浏览器窗口的高度。现在有了vh这个单位,就不再需要考虑父级元素的 height 值,也不需要自己去获取浏览器高度。
我认为这两个单位实用价值还是挺高的,在写css的时候,经常会被高度和宽度这两个样式弄得很头痛。要保证界面有一定自适应效果,就不能用 px,用百分比又得确保父元素的高度和宽度是正确的。所以用好 vwvh 能保证样式效果还不用考虑其他问题。

参考文章:

CSS: em, px, pt, cm, in…
CSS values and units
综合指南: 何时使用 Em 与 Rem