根本区别在于参照物不同:em 相对于父元素 font-size,rem 始终相对于根元素 html 的 font-size;前者易因嵌套叠乘失控,后者便于全局统一控制。

rem 和 em 的根本区别在哪
区别不在“r”和“e”,而在**参照物不同**:em 相对于父元素的 font-size,rem 始终相对于根元素(html)的 font-size。这意味着嵌套越深,em 越容易“叠乘失控”——比如三层 div 各设 font-size: 1.2em,最内层实际是 1.2 × 1.2 × 1.2 = 1.728 倍,而 rem 始终只看 html 标签那一个值。
常见错误现象:margin: 1.5em 在子组件里突然变大,调试发现父容器改过 font-size 却没意识到它会影响所有后代的 em 计算。
- 用
em适合做「相对缩放」:按钮内边距随文字大小等比变化、图标尺寸随父字号自适应 - 用
rem更适合「全局尺度控制」:整个页面的间距、圆角、阴影统一按根字号缩放 - 不要混着用同一套设计系统里的基础间距变量——比如
$space-md: 1.5rem和$space-md: 1.5em并存,后期换根字号时em部分会意外失效
移动端适配中 rem 的典型实现方式
主流做法是 JS 动态设置 html 的 font-size,让 1rem 对应 1px(或 10px)便于计算。例如设计稿宽 375px,希望 1rem = 10px,则 html 的 font-size 应为 10 * (deviceWidth / 375)。
但要注意:iOS Safari 在横屏切换时不会自动触发 resize,需监听 orientationchange;部分安卓 WebView 对 screen.width 返回值不准确,建议用 window.innerWidth。
- 推荐用
document.documentElement.style.fontSize = fontSize + 'px'设置,避免操作html元素本身引发重排 - 别在 CSS 里写死
html { font-size: 16px },否则 JS 设置会被覆盖(除非加!important,不推荐) - 使用
postcss-pxtorem自动转换时,确认其配置的rootValue与 JS 运行时一致,否则开发和上线尺寸对不上
em 在组件内部微调时更自然
当你写一个按钮组件,希望 padding 随文字大小缩放,又不想被外部 html 字号干扰,em 就比 rem 更合适。它天然继承当前上下文的文字尺寸,不需要额外绑定根节点逻辑。
常见错误现象:用 rem 写按钮 padding: 0.75rem 1.5rem,结果在小字号卡片里按钮显得过大,在大标题下又显得局促——因为它的基准脱离了组件自身字体。
-
line-height: 1.5本质就是1.5em,无需显式写单位,这是 CSS 默认行为 - 图标类
font-icon或svg容器用width: 1.2em可保证始终与文字等高,比固定16px或1rem更鲁棒 - 慎用
em控制非文字相关尺寸(如容器宽度、最大高度),容易因父级无意中设置了font-size导致布局错乱
vw/vh 什么时候比 rem/em 更合适
当需要「严格按视口比例伸缩」时,vw 比 rem 更直接。比如全屏 banner 高度设为 height: 80vh,比用 JS 算 rem 值再设更轻量、无延迟。
但要注意兼容性:IE9+ 支持 vh,但 iOS Safari 7.1–9.3 有 bug,vh 会按初始视口计算,键盘弹出后不更新;Android 4.4 以下也存在类似问题。
- 全屏背景图、模态框遮罩层高度、响应式字体(
font-size: clamp(1rem, 4vw, 2rem))优先考虑vw/vh - 避免用
100vh做页面最小高度——Safari 地址栏收起/展开时会触发重绘,导致内容跳动;改用min-height: 100%+html, body { height: 100% } -
rem和vw不要混用于同一数值体系,比如把设计稿 10px 当作 1rem,又同时用20vw表示某个宽度,后期维护时换算关系会断裂
真正难的不是选 rem 还是 em,而是保持整个项目里「缩放锚点」的一致性。一个组件用 em 做内边距,另一个用 rem 做外边距,再套一层用 vw 做最大宽度——这种混合一旦形成,后续任何人想调整基础字号,都得翻遍所有样式查依赖链。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











