CSS变量必须声明在:root中才能全局生效,因其是唯一确保全文档继承、主题切换和响应式复用的原生方案;媒体查询重定义、JS动态修改及calc()运算均需遵循此作用域规则。

它不是“锦上添花”的特性,而是解决主题切换、组件定制、响应式复用这三类高频问题的最小可行原生方案——没有它,就得靠 JS 拼字符串、引入 CSS-in-JS 库,或者退回 Sass 多套变量文件的手动维护时代。
var() 读不到值?先查作用域链
写完 --color-primary: #007bff 却渲染不出颜色,90% 是因为变量没声明在可继承的作用域里。浏览器不会自动“扫描全局”,必须显式挂载。
-
:root最安全:等价于html元素,所有元素默认继承 - 局部声明只对后代生效:比如在
.card里写--bg: #fff,那只有.card内部能用var(--bg) - 伪类中声明是合法的:例如
.btn:hover { --opacity: 0.8; },但该变量仅在此状态下生效,且不触发重排——这是纯 CSS 实现暗色悬停的关键
JS 动态改主题,别直接赋值 style 对象
el.style.--foo = 'red' 是无效语法。CSS 自定义属性不能像普通 CSS 属性那样通过点号访问 style 对象。
- 改全局变量:用
document.documentElement.style.setProperty('--text-color', '#1a1a1a') - 改局部变量:用目标元素的
style.setProperty(),比如headerEl.style.setProperty('--border-width', '2px') - 读取值必须用
getComputedStyle(el).getPropertyValue('--foo'),注意返回值带首尾空格,要用.trim()
媒体查询里重定义变量,必须写在 :root 下
想根据屏幕宽度动态调整 --gap 或 --font-size?别把变量塞进 @media 里的组件选择器里——那样会断掉继承链,后代拿不到新值。
立即学习“前端免费学习笔记(深入)”;
- 正确写法:
@media (min-width: 768px) { :root { --gap: 1.5rem; } } - 错误写法:
@media (min-width: 768px) { .container { --gap: 1.5rem; } }—— 此时.container子元素无法继承这个新值 - 变量值支持
calc(),但var()不能直接参与外部运算:写width: var(--size) * 2会报错,必须写成width: calc(var(--size) * 2)
真正容易被忽略的,是变量值的“运行时计算”能力——它不像 Sass 那样编译期展开,而是在每次样式计算时实时求值,这意味着它能响应 JS 修改、媒体查询切换、甚至伪类状态变化,但同时也要求你始终关注继承路径和 calc() 的包裹规则。


















