rem控制全局缩放,em负责文字关联微调;rem依根字号等比缩放,避免嵌套失控,em则绑定直接父级字号用于内边距、图标等局部比例适配。

直接结论:rem 控制全局缩放节奏,em 负责文字关联微调;混用没问题,但必须分清谁管“尺度”,谁管“节奏”。
为什么 rem 是响应式字体的主干单位
rem 始终参照 html 的 font-size,改一次根字号,所有 1rem、2.5rem 都同步等比变化——这是实现“页面级缩放”的唯一可靠路径。嵌套再深,也不会像 em 那样叠乘失控。
- 常见错误现象:
font-size: 1.2em在三级嵌套后变成预期的 1.728 倍,调试时发现父级某个div意外设置了font-size: 1.5em,导致整个区域文字失衡 - 移动端典型做法:用 JS 动态设
document.documentElement.style.fontSize = (window.innerWidth / 375) * 16 + 'px',让设计稿 375px 宽对应 16px 根字号,其他宽度自动插值 - 兼容性注意:iOS Safari 横屏不触发
resize,需额外监听orientationchange;部分安卓 WebView 的screen.width不准,优先用window.innerWidth
em 该用在哪些具体位置
em 的价值不在缩放,而在“绑定文字”。它只响应**直接父级**的 font-size,适合那些必须和当前文字尺寸保持比例关系的局部元素。
- 按钮内边距:
padding: 0.75em 1.2em—— 文字变大,留白自然撑开,不会出现文字顶到边框的情况 - 图标尺寸:
.icon { font-size: 1.2em; },确保 SVG 或字体图标始终与相邻文字垂直对齐 - 伪元素装饰:
::before { font-size: 0.8em; },让小圆点、分隔符等严格贴合主文字大小 - 绝对不能用 em 控制容器宽高或
flex-basis,否则父级一调字号,布局就连锁错位
根字号设置的两种实操路径
JS 动态计算最灵活,clamp() 纯 CSS 更轻量。二者不是二选一,而是可共存兜底。
立即学习“前端免费学习笔记(深入)”;
- JS 方案要早执行:放在
<head>内或DOMContentLoaded早期,避免 FOUC(闪屏);别等window.onload,图片加载完才跑就晚了 -
clamp()推荐写法:font-size: clamp(14px, 2.5vw, 18px)—— 注意三值单位必须一致(全用px或全用vw),混用如clamp(14px, 2.5vw, 1.125rem)会失效 - 实际搭配建议:用
clamp()设html { font-size }保底,再让所有组件用rem继承;第三方 UI 库若内部用em,加font-size: 1rem到组件根节点切断上游干扰
容易被忽略的细节和兼容边界
真正上线时卡住的,往往不是逻辑,而是这些具体约束。
- 别用
62.5%技巧(即设html { font-size: 62.5% }让1rem = 10px):它依赖浏览器默认 16px,用户手动调大系统字号时会失效,无障碍体验差 - 行高别写
px:统一用无单位值,如line-height: 1.6,它会自动按当前font-size计算,和rem/em字体天然同步 - 测试时务必检查
font-size: 0容器:某些 UI 框架为清除列表项间距会设这个,会导致所有em归零,组件根节点加font-size: 1rem就能兜住 - rem 不是万能的:超小屏(min-font-size 还没普及,用
clamp()或媒体查询兜底)


















