CSS 里能写长度的地方,px、em、rem、vw 随便选一个都能生效,但它们代表的"多长"是相对于完全不同的基准算出来的——不搞清楚这一点,页面在不同设备上就容易出现意料之外的缩放效果。
px(像素)是最直观的单位,理论上代表屏幕上的一个物理像素点(现代高分屏下浏览器会做设备像素比换算,但对 CSS 而言可以理解为一个固定不变的逻辑单位)。它的特点是不随任何上下文变化——写死 16px 就是 16px,不管父元素字号多大、用户有没有调整浏览器默认字号。这个"绝对"既是优点(简单可控)也是缺点(不利于响应式和无障碍缩放)。
em 的值是相对当前元素的字号(或父级继承来的字号)计算的:1em 等于当前元素的字号大小。这带来一个常见的坑——em 会累积:如果一个元素设置 font-size: 1.2em,它的子元素再设置 padding: 1.2em,子元素的 padding 实际值是基于父元素算出来的字号再乘 1.2,如果嵌套层级很深、每层都用 em 设置字号,实际尺寸会一层层滚雪球式放大或缩小,变得难以预测。
rem(root em)的设计正是为了解决 em 的累积问题:不管嵌套多少层,1rem 永远只相对于根元素(html)的字号计算,不受中间任何父级元素字号的影响。这也是为什么现代前端项目普遍推荐用 rem 而不是 em 来做整体页面的字号和间距——只需要调整根元素的字号(比如做整站字号的响应式缩放),所有用 rem 定义的尺寸会统一等比例缩放,而不会因为嵌套层级产生不可控的复合效应。
vw(viewport width)和 vh(viewport height)是相对浏览器视口尺寸计算的:1vw 等于视口宽度的 1%,1vh 等于视口高度的 1%。这类单位天然适合做"占屏幕多大比例"的响应式布局——比如想要一个元素始终占屏幕宽度的一半,写 50vw 比用固定 px 值再配合媒体查询更直接。需要注意移动端浏览器的地址栏收起/展开会动态改变视口高度,vh 在移动端有时会出现跳动,这是浏览器视口计算方式带来的已知问题。
没有哪个单位绝对更好,选择依据是"这个尺寸该不该跟着字号/视口变化",这个问题想清楚了,用哪个单位自然就有答案。
在线工具:CSS单位互转