<p>应使用 :root 伪类定义全局 CSS 变量,因其语义准确、优先级略高且跨文档一致;变量名必须以 -- 开头,var() 中未定义或拼错时才启用 fallback 值。</p>
必须在 :root 里用双破折号开头声明,否则不是全局变量,也不会被 var() 读到。
:root 而不是 html 或其他选择器:root 是 CSS 规范定义的根作用域选择器,语义准确、优先级略高于 html,且在 SVG 等非 HTML 文档中也保持一致行为。写成 html { --color: red; } 虽然多数情况下“看起来有效”,但属于误用——它只是普通元素选择器,不保证在所有上下文(比如 Shadow DOM 或嵌入文档)中生效。
常见错误包括:
.theme-dark 这类 class 里,结果只有该 class 内部能读取,外部 var(--color) 返回空字符串或 fallback 值<style> 标签底部才声明 :root 变量,但上面的规则已提前用了 var(--color) → 浏览器按顺序解析,未声明即无效--,比如写成 primary-color: #007bff,浏览器直接忽略整条声明,无报错var() 的 fallback 值到底什么时候起作用fallback 不是“备选主题”,而是纯粹的降级兜底:只在变量未定义、拼写错误、或语法非法(如 var(--color, ) 少了值)时启用。它不会做条件判断,也不能嵌套另一个 var()。
立即学习“前端免费学习笔记(深入)”;
正确写法示例:
color: var(--text-primary, #333);
错误写法(整条声明失效):
color: var(--text-primary, var(--text-default));
注意点:
16px、"bold"、rgb(0,0,0))var(--xxx) 显示 invalid,基本就是变量名拼错、没声明、或 fallback 写法非法[data-theme] 选择器控制:root 变量要注意什么用 document.documentElement.style.setProperty() 确实能实时更新所有依赖该变量的样式,但有几个硬限制:
getComputedStyle(document.documentElement).getPropertyValue('--primary') 返回 " #007bff ",记得 .trim()
style 属性里声明新变量(<div style="--x:red">),这种声明仅对该元素生效,不进入全局作用域setProperty()(如每帧一次)可能引发样式计算抖动,批量修改建议先拼好 cssText 再一次性赋值@media 中引用其他变量,比如 @media (prefers-color-scheme: dark) { :root { --bg: var(--bg-dark); } } 会失败真正容易被忽略的是变量继承链和层叠顺序:哪怕你写了 :root { --c: red; },如果某个父元素又写了 .wrapper { --c: blue; },那它内部所有 var(--c) 都会取 blue —— 这不是 bug,是 CSS 自定义属性的就近原则,但常被误以为“主题没切成功”。