rem基于根元素font-size等比缩放,适合全局响应式;em随父级逐层累积,易致嵌套失控;vw随视口线性变化但需clamp()限幅;推荐rem+vw混合使用以兼顾稳定性与弹性。

rem 设置字体大小依赖根元素 font-size
rem 是相对于根元素(html)的 font-size 计算的。页面中所有用 rem 定义的字体,都会随 html 的 font-size 等比缩放,这是实现响应式文字的基础。
常见做法是用 JS 动态设置 html 的 font-size,比如按屏幕宽度等比例缩放:
document.documentElement.style.fontSize = document.documentElement.clientWidth / 375 * 16 + 'px';
这里以 375px 设计稿为基准,16px 为 1rem 原始值;也可用媒体查询配合 CSS 实现简单分段适配:
@media screen and (max-width: 375px) { html { font-size: 14px; } }
@media screen and (min-width: 376px) and (max-width: 768px) { html { font-size: 16px; } }
@media screen and (min-width: 769px) { html { font-size: 18px; } }- 注意:JS 设置需在 DOM 加载后执行,且监听
resize和orientationchange防止横竖屏切换失效 - 若使用了
lib-flexible或postcss-pxtorem,要确认其基准值(通常是 375 或 750)与设计稿一致,否则转换错乱 -
rem对嵌套层级不敏感,适合全局统一控制,但无法响应容器尺寸变化
em 在嵌套中会逐层累积缩放
em 是相对于父元素 font-size 的单位,子元素用 em 时,会继承并基于父级当前计算值继续缩放。这容易导致深层嵌套时字体失控。
立即学习“前端免费学习笔记(深入)”;
例如:html 设为 16px,.box 设 font-size: 1.2em(即 19.2px),其子元素写 font-size: 1.2em 就变成 19.2 × 1.2 ≈ 23px,而非预期的 16 × 1.2 × 1.2。
- 适合局部微调,比如按钮内图标字号跟随文字大小:用
font-size: 0.8em表示“取父级字号的 80%” - 避免在多层组件中混用
em控制主体文字,尤其在 Vue/React 组件嵌套深时极易失准 - 重置样式中
body { font-size: 1em; }是安全的,因它直接继承html,不引入额外缩放
vw 单位让字体随视口宽度线性变化
vw 表示视口宽度的 1%,100vw = 浏览器窗口宽度。用它设字体可实现真正的流体缩放,比如 font-size: 4vw 表示字体始终占屏幕宽的 4%。
但纯 vw 有明显缺陷:小屏下过小(如 iPhone SE 上 4vw ≈ 12px)、大屏下过大(桌面端可能超 40px),可配合 clamp() 限定范围:
font-size: clamp(14px, 4vw, 28px);
-
clamp(min, preferred, max)中间值优先,超出范围则卡在边界,现代浏览器支持良好(Chrome 88+、Firefox 79+、Safari 13.4+) - 不用
clamp()时,可用媒体查询兜底:@media (max-width: 320px) { font-size: 14px; } - 慎用于长段落正文——线性缩放不符合阅读习惯,用户可能在中等尺寸设备上遭遇突兀大小跳变
混合使用 rem + vw 是更稳妥的自适应方案
单独用任一单位都有短板:rem 需手动设定断点或 JS 计算,em 易受嵌套干扰,vw 缺乏上下限保护。实际项目中,推荐用 rem 做基准 + vw 做微调。
例如给标题设一个带弹性的字号:
h1 { font-size: clamp(1.5rem, 4.5vw, 3rem); }这样既保留了 rem 的可维护性(基础值清晰),又通过 vw 实现平滑过渡,还用 clamp() 锁死最小最大值。
- 设计稿标注为 32px 的标题,在 375px 屏幕下对应
2rem(以 16px 为 1rem),再叠加vw得到弹性区间 - 字体渲染在小字号下(vw 的 subpixel 渲染也不稳定,务必在真机测试
- 如果项目需兼容 IE,只能退回 JS + rem 方案,并用
resize节流防抖










