CSS: Values and Units: Distance Units

 20th August 2020 at 2:19pm

一开始 web 界很倾向于 Pixel perfect 这个理念,各种布局都精确到了像素点,比如很长一段时间网页内容都是居中在一个固定的 800px 左右的容器中。但是后来 PC 的屏幕越来越大,同时手机屏幕也出现了,导致一个固定的布局无法适应多种设备。因此业界的实践也从大量使用绝对的长度单位,转向使用相对单位。

Absolute length units

UnitNameEquivalent to
cmCentimeters1cm = 96px/2.54
mmMillimeters1mm = 1/10th of 1cm
QQuarter-millimeters1Q = 1/40th of 1cm
inInches1in = 2.54cm = 96px
pcPicas1pc = 1/16th of 1in
ptPoints1pt = 1/72th of 1in
pxPixels1px = 1/96th of 1in

总结:1 in. = 25.4 mm = 2.54 cm = 6 pc = 72 pt = 96 px

CSS 中的像素(px)跟显示器的像素是不一样的。对于一个典型的 23.8 英寸 1080P 分辨率的显示器,显示器的 PPI 是 92,屏幕的物理尺寸为 527.04mm x 296.46mm(20.75" x 11.67")。在系统缩放比例保持 100% 并且浏览器也不做额外缩放的情况下,1 CSS inch 在屏幕上的长度大约是 1.04 英寸(96/92)。填满 1080 个像素点,需要 20(1080 / 96)个 CSS inch,需要 20.86(1080 / 92)个英寸。

CSS 单位到屏幕单位的换算,在 Media query 部分再详谈。

Relative length units

相对长度的 CSS 单位。这里只关心跟字体大小相关的属性 emrem

  • em: Font size of the element.
  • rem: Font size of the root element.

使用相对单位会使得整个样式表的维护性增强(比如你不需要修改到处都是的 px 值),也会使得应用响应式设计更加简单。

em

.padded {
  padding: 1em;    
}

padding 的数值在运行时才会被计算出来,在该属性应用到的元素上,它的 padding 值与其 font-size 值一致。比如该元素的 font-size16px,那么 padding 的值也为 16px。这种值被称为 computed valueem 可以用来实现按不同的字体大小给定不同 padding, height, width, border-radius 等功能,比如:

这是另外一个示例,用来实现不同大小的 box:

对于 font-size 本身,也可以使用 em 单位,会在它继承的 font-size 基础上乘上 em 的比例:

如果对不同属性同时使用 em,可能会有些没那么直观的效果:

在嵌套元素中使用 em 时,会造成一个 shrinking font problem,具体看 CSS in Depth: Ch02 书中示例。

rem

相较于 em,还有一个 rem,它跟 em 的区别是它是相对于 root element,对于一个普通的 HTML 来说即是 <html> 元素。一般页面不会对这个元素设置 font-size,因此 rem 单位用在 font-size 上时,一般是相对于浏览器预设的字体大小。而这个大小,一般默认为 16px(medium)。

rem 的好处在于增强了无障碍性(accessibility)。比如对于视障人士,如果它期望页面的字体更大,他可以用两种方式:

  • 使用浏览器提供的缩放功能,一般是 Ctrl-= 这类快捷键
  • 将浏览器默认的字体大小调得更大

如果一个网站在设置 font-size 时都用 rem 作为单位,那么上述的第二种方式是有效的。但是大多数网站,特别是电商网站,大量用了 px 来表示字体大小。考虑到电商网站的 UI 一般比较复杂,使用 px 可能对于他们设计网站样式时更有帮助,但是这损伤了无障碍性。现代网站的样式设计应该多用 rem 来表示字体大小。

最佳实践:

对于什么时候用绝对值,什么时候用 emremCSS in Depth 给出了普适(但不绝对)的经验:

When in doubt, use rems for font size, pixels for borders, and ems for most other properties.

Bulma 的 样式,是符合上述规则的。对于线段式的样式(比如 border 等),用 px 能更精确地控制线的样子。对于诸如 padding 等跟间隔相关的,用 em 可以跟内容契合。我认为 border-radius 这种即可以用 em 也可以用 px,视你是否想让圆角跟着内容大小变化。

应用实例:

用相对值方便做不同大小的 panel 设计: