必须将CSS变量通过var()绑定到:root的font-size上,否则rem单位无法响应变化;仅定义变量而不绑定、漏掉var()引用、单位缺失、JS修改时未带单位或媒体查询覆盖,均会导致失效。

必须把 CSS 变量绑定到 :root 的 font-size 上,否则所有 rem 单位都不会响应变化。
为什么只定义变量却没效果?
很多人写 :root { --font-base: 16px; } 就以为完事了,但浏览器根本不会“自动把 rem 换算成这个变量”。真正驱动缩放的是根元素的 font-size 值本身。
- 错误写法:
:root { --font-base: 16px; }(变量存在,但没被用) - 正确写法:
:root { font-size: var(--font-base, 16px); }(显式绑定,rem才能联动) - 漏掉
var()引用:比如.title { font-size: 1.5rem; }→ 即使--font-base改了,它也不动 - 单位缺失:写成
--font-base: 16(缺px或rem),var()引用时静默失败
JS 动态修改时最容易踩的坑
用 document.documentElement.style.setProperty() 更新变量是唯一可靠方式,但细节决定成败。
- 必须带单位:
setProperty('--font-base', '18px'),不能只传数字18 - 别在媒体查询里重复设
font-size,否则会覆盖 JS 设置的值 - 初始值建议在
:root中声明::root { --font-base: 16px; font-size: var(--font-base); } - 测试时直接在开发者工具 Elements 面板改
:root的font-size,看布局是否整体等比响应
用 rem 还是直接改 font-size?
如果只调字体大小,直接改 :root { font-size: 14px; } 最省事;但如果还要同步控制 padding、line-height、border-radius,用变量更统一。
立即学习“前端免费学习笔记(深入)”;
-
rem始终相对根元素,可控性强;em是相对父元素,嵌套深了容易失控 - 第三方组件若内部用
em(如某些 UI 库按钮的padding),它不会随rem缩放同步变化,视觉比例可能错乱 -
clamp(1rem, 1.2rem, 1.5rem)能随根字体变,但clamp(16px, 2vw, 24px)不会——里面全是绝对或视口单位,和变量无关
最关键的细节常被忽略:CSS 变量本身不响应任何变化,它只是个“容器”;真正触发重绘的是你把它用在了 :root 的 font-size 上,并且其他样式确实依赖 rem 或 calc(var(--x) * 1rem) 这类表达式。少一个环节,整个链路就断了。


















