px适用于尺寸需绝对固定场景,如边框、小图标、border-radius等;em依赖上下文易失控,仅适合层级≤2的局部缩放;rem依赖html font-size,需显式设置并配合clamp或js动态调整。

别纠结“哪个更好”,先看这个元素该听谁的——px不听任何人,em只听父级font-size,rem只听html的font-size。选错不是写错,是绑错了参照物。
什么时候必须用 px
当尺寸不能随任何上下文变化时,px是唯一能兜底的选择。
-
border:比如border: 1px solid #ccc——字体放大、视口缩放、系统字体设置,都不该影响边框粗细,否则视觉节奏全乱 - 小图标/装饰线:
width: 24px、height: 24px——设计稿给的是像素值,就该原样落地,不然对不齐 -
border-radius和box-shadow偏移量:比如border-radius: 4px、box-shadow: 0 2px 8px——这些值靠手感调出来,放大后失真会破坏 UI 精致感
注意:px在 Retina 屏模糊,不是单位问题,是渲染策略问题;用transform: scale(0.5)配2px边框可修复,但基准值仍得是px。
em为什么越用越失控
em不是“相对于父元素”,而是“取决于它用在哪”:在font-size上,它看父级;在padding、margin上,它看自身当前的font-size。
- 正确用法:
.btn { font-size: 16px; padding: 0.5em 1em; }→ 内边距基于按钮自己的字号,字号变,内边距等比缩放 - 危险嵌套:
.menu li { font-size: 1.2em; } .menu li ul li { font-size: 1.2em; }→ 第三级实际是16px × 1.2 × 1.2 = 23.04px,根本没法预期 - 常见报错现象:
font-size: 1.5em写出来比预期大很多,十有八九是父级已经放大过,你没意识到
一句话:em只适合明确知道上下文、且层级≤2的局部场景,比如按钮里的图标对齐、卡片标题区文字缩放。别让它跨组件传播。
rem写了却没响应?根字号没管住
rem不是“写了就响应”,它只认html元素最终计算出的font-size值,其他全是幻觉。
- 必须显式设:
html { font-size: 16px; }——别依赖浏览器默认,iOS Safari 有时会重置 - 响应式推荐写法:
html { font-size: clamp(14px, 4vw, 18px); }——小屏保可读性,大屏不撑爆,中间流体过渡 - JS 动态调整时,改的是
document.documentElement.style.fontSize,不是body - 无障碍场景下,用户系统字体放大(如 macOS「显示缩放」),
rem会自动跟随,px不会
容易忽略的一点:CSS自定义属性var(--base-font)不能直接参与rem计算,rem只认html元素的最终计算值,不是变量名。
混用单位时最常踩的坑
真实项目里px、em、rem往往共存,冲突点集中在“参照物打架”。
- 同一套间距系统里同时出现
1rem和1em,等于主动放弃可维护性 - 写
.card { font-size: 1.2em; },而它的父级是1.5rem→ 实际计算是1.5rem × 1.2,再向上找父级的font-size,链式依赖极难追踪 - 用
rem但忘了重置html的默认字号(Chrome 是16px)→ 所有1rem默认等于16px,改了设计稿基准(比如按10px = 1rem)却不改html→ 全站字号错乱
复杂点不在换算公式,而在参照链是否清晰——一个em值背后可能藏着三层父级字号叠加,而rem只要盯着html就行。真正难的,是决定这个元素该听谁的。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











