必须修改html的font-size才能实现rem响应式,因为rem只相对于根元素计算;默认16px下1rem恒为16px,不改根字号则rem等同于px。

rem 为什么必须改 html 的 font-size 才能响应式
因为 rem 只认根元素,不是 body 或任何父容器。浏览器默认 html { font-size: 16px },所以 1rem 永远等于 16px —— 除非你主动改它。不碰 html 的 font-size,只把 font-size: 1.2rem 写满 CSS,和写 px 几乎没区别。
常见错误包括:
- 在
body上设font-size: 18px,以为子元素用rem就会变大 —— 实际不会,rem不继承body - 用
em混着写,嵌套三层后1.2em算出来是 16 × 1.2 × 1.2 × 1.2 ≈ 27.6px,完全失控 - 只写媒体查询硬编码
html { font-size: 14px; }、html { font-size: 18px; },断点之间字体跳变,小屏到中屏可能突然放大 20%
用 clamp() 直接在 CSS 里动态控制 html 字号
现代方案首选 html { font-size: clamp(14px, 2.5vw, 18px); } —— 它比 JS 更轻量、无阻塞、天然支持 SSR 和系统缩放。
注意三点:
-
clamp(最小, 当前值, 最大)中的2.5vw是关键:视口每宽 100px,字号增加 2.5px;iPhone SE(375px)≈ 9.4px → 实际取最小值14px;iPad Pro(1024px)≈ 25.6px → 实际取最大值18px - 不能直接对
h1用clamp(1rem, 4vw, 2.5rem),因为1rem此时还是依赖未动态化的根字号,会失效 - iOS Safari 对
0.5rem这类极小值有渲染四舍五入行为(比如实际画成 8px 而非 7.5px),所以正文慎用(即
JS 动态设置 document.documentElement.style.fontSize 的实操要点
当需要兼容老浏览器、或要结合 DPR(设备像素比)、系统字体缩放时,JS 方案更可控。但容易踩坑:
- 必须在
DOMContentLoaded后执行,否则document.documentElement可能还没 ready - 别在
resize里直接设fontSize,高频触发会导致卡顿;要用requestAnimationFrame或 throttle(如 Lodash 的throttle(fn, 100)) - 横屏切换时
window.innerWidth突然变大,但视觉宽度没变(比如 iPad 横屏 1024px,但实际内容区仍按竖屏逻辑排版),建议用document.documentElement.clientWidth更稳 - 公式推荐:
100 * clientWidth / 375(以 iPhone SE 宽为基准),得出的数值单位是px,直接赋给style.fontSize即可
rem 和 vw 混用时怎么避免小屏文字不可读
标题用 vw、正文用 rem 是合理组合,但必须加限制 —— 否则 iPhone 上 5vw 只有 18.75px,再叠加载字体渲染误差,可能 barely 可读。
安全做法:
- 大标题优先用
clamp(1.25rem, 4.2vw, 2.25rem):最小保证 20px(1.25 × 16),最大封顶 36px(2.25 × 16),中间用vw平滑过渡 - 正文字号统一走
rem,比如font-size: 1rem(配合根字号动态变化),行高用无单位值如line-height: 1.5,自动随字号缩放 - 禁用纯
vw做段落文字:小屏下3vw在 320px 屏上仅 9.6px,远低于 WCAG 最小可读标准(12px)
最易被忽略的是系统级缩放:Windows「显示设置」调到 125%,或 macOS「显示器缩放」开「更大文本」,此时 vw 不变但实际渲染字体被系统拉伸,而 rem 会跟随 —— 所以根字号动态逻辑里最好也读取 window.devicePixelRatio 和 matchMedia('(min-resolution: 1.25dppx)') 做微调。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











