rem更适合响应式,因其只依赖html根元素font-size,改一处全站等比缩放;em依赖父元素且基准动态切换(font-size看父级、padding/margin看自身),嵌套后易因连乘失控。

rem 更适合响应式,不是因为它“更现代”,而是它只依赖 html 的 font-size,改一个值,全站尺寸等比缩放;em 依赖父元素,嵌套两层后,1.2em 到底是多少像素,得手动逆推三遍。
为什么 em 在嵌套中会“算丢”
em 的参照物会动态切换:用在 font-size 上时看父元素,用在 padding 或 margin 上时却看自身当前的 font-size。这种双基准机制在多层组件里极易失控。
- 父容器设
font-size: 20px,子元素写font-size: 1.5em→ 实际 30px - 该子元素再设
padding: 1em→ 不是 20px,而是 30px(以自己字号为基准) - 若父容器本身也是用
1.2em算出来的,那最终值就是连乘:16px × 1.2 × 1.5 × 1 = 28.8px
调试时你看到的 margin: 1.5em 在弹窗里突然变大,八成是某层父容器悄悄改了 font-size,而你根本没意识到它会影响所有后代的 em 计算。
rem 的响应式核心不在“r”,而在根字号是否真能动
光写 html { font-size: 16px } 是假响应式——那是固定尺寸。真响应的关键是让根字号随视口变化,且变化平滑、有依据。
- 最轻量方案:
font-size: 2.666vw(即 375px 设计稿下 1rem = 10px),但 iOS Safari 12 及更早不支持 - 兼容性兜底:
clamp(14px, 2.5vw, 18px),Safari 13.1+ / Chrome 88+ 支持良好 - JS 方案慎用:必须防抖 resize,并监听
orientationchange(iOS 横屏不触发 resize) - 别在 CSS 里写死
html { font-size: 16px },否则 JS 设置会被覆盖
em 并非无用,只是适用场景非常具体
em 的价值不在全局响应,而在局部上下文跟随。它天然继承当前文字尺寸,不需要绑定根节点逻辑。
- 按钮组件内:
padding: 0.75em 1em能让内边距随按钮文字大小等比缩放,不受外部html字号干扰 - 图标字体(icon-font)对齐文本基线:
font-size: 0.875em可保证图标始终与当前文字行高匹配 - border-width 需要按文字粗细比例缩放时,
border: 0.125em solid比写死2px更合理
混用是最大隐患:同一套间距变量里同时出现 1.5rem 和 1.5em,等于主动放弃可维护性。后期换根字号,em 部分会意外失效,还查不出原因。
真正难的不是选 rem 还是 em,而是守住参照系边界——一旦开始用 rem 做全局尺度,就别让某个父容器偷偷改 font-size;一旦用 em 做局部缩放,就别指望它能响应屏幕宽度。单位本身没对错,错的是参照逻辑被悄悄污染。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











