px rem em 单位换算
同一个长度换成 px、rem、em、vw、vh、pt,根字号和视口变了结果也跟着变。
绝对像素,不随字号和视口变化
换算结果
16px
- px
16px绝对值 - rem
1rem按根字号 16px - em
1em按父级字号 16px - vw
1.1111vw按视口宽 1440px - vh
1.7778vh按视口高 900px - pt
12pt1pt = 96/72 px - %
100%相对父级字号 16px
常见 px 到 rem 对照
按当前根字号 16px 换算。
| px | rem |
|---|---|
| 8 | 0.5 |
| 10 | 0.625 |
| 12 | 0.75 |
| 14 | 0.875 |
| 16 | 1 |
| 18 | 1.125 |
| 20 | 1.25 |
| 24 | 1.5 |
| 28 | 1.75 |
| 30 | 1.875 |
| 32 | 2 |
| 36 | 2.25 |
| 40 | 2.5 |
| 48 | 3 |
| 56 | 3.5 |
| 64 | 4 |
| 72 | 4.5 |
| 80 | 5 |
| 96 | 6 |
| 120 | 7.5 |
单位依赖什么
px 是绝对单位,也是其他单位换算的中转站。rem 只依赖根元素字号:浏览器默认是 16px,所以 1rem = 16px、0.875rem = 14px。常见做法是把 html 的字号设成 62.5%,让 1rem = 10px,这样设计稿上的 14px 直接写 1.4rem,心算方便;代价是用户如果改了默认字号,比例会跟着变。
em 和 % 依赖父级字号,而且会嵌套累乘。父级设了 1.5em,子级再设 1.5em,实际是 2.25 倍,这就是「明明写了 1.5em 却大得离谱」的原因。% 在字号上是相对父级字号的百分比,100% 等于 1em,两者可以互相替换。做组件内部的自适应间距时用 em 很合适,做全局尺寸就不合适。
vw 和 vh 的陷阱
vw 是视口宽度的百分之一。视口宽度会随纵向滚动条出现而变小,桌面浏览器里 100vw 通常比实际可用宽度多出滚动条那十几像素,于是出现横向滚动。用 width: 100% 更稳。vh 在移动端的问题更明显:地址栏收起前后可视高度不同,100vh 是按较大的那个算的,底部内容可能被裁掉,现代浏览器提供了 dvh 来按动态视口计算。
可访问性与最小字号
字号建议用 rem 而不是 px,这样用户在浏览器里调大默认字号时页面会跟着放大。Chrome 对小于 12px 的中文有最小字号限制,设 10px 实际仍按 12px 渲染,这不是换算错了。pt 在 CSS 里固定等于 96/72px,和物理 DPI 无关,所以 12pt 永远是 16px。要处理设计稿里的颜色和间距,可以配合颜色转换和Flex 与 Grid 布局生成一起用。
常见问题
rem 和 em 到底差在哪?
rem 只认根元素(html)的字号,整页只有一个基准,所以用 rem 做间距和字号最稳定。em 认的是当前元素的父级字号,父级变了子级跟着变,嵌套几层就会累乘:父级 1.5em、子级又 1.5em,实际是 2.25 倍。适合需要「跟着上下文缩放」的场合,不适合做全局尺寸。
为什么 14px 转成 rem 是 0.875?
14 / 16 = 0.875,这是根字号为 16(浏览器默认)时唯一的结果。只有改过 html 的 font-size,比如移动端设成 62.5% 让 1rem = 10px,结果才会变。页面上可以把根字号改成 10 再算一遍,对照两种方案。
该用 px 还是 rem?
字号和依赖字号的比例用 rem(或 em),边框、阴影、1px 细线用 px。全用 px 的问题在于用户改了浏览器默认字号后页面不跟着放大,属于可访问性问题。另一个折中是 clamp() 配合 rem,让字号随视口平滑变化,但要注意设置上下限。
vw 和 vh 能放心用来做全屏布局吗?
要小心。100vh 在移动端浏览器里包含地址栏区域,地址栏收起时元素会被裁掉一截,所以现在更推荐 100dvh(动态视口高度)。vw 的问题是出现纵向滚动条时视口宽度会变小,100vw 可能比实际可用宽度多出十几像素,造成横向滚动。
为什么小于 12px 的字在页面上看起来比设定的大?
Chrome 和部分浏览器有最小字号限制,默认不会渲染小于 12px 的中文,设定 10px 实际仍按 12px 显示。这不是换算错误,而是浏览器行为。需要更小的字时,通常要靠缩放整个容器(transform: scale)而不是继续压字号。
pt 和 px 是固定比例吗?
在 CSS 里是:1pt 等于 96/72 px,也就是 1.3333px,和屏幕实际 DPI 无关。所以 12pt = 16px。打印样式里 pt 更常见,屏幕上一律按这个比例换算即可,不需要知道显示器是多少 DPI。