css自定义变量必须声明在:root选择器内,因它是规范指定的全局锚点,特异性更高且跨文档兼容;裸写顶层、用html/body声明或语法错误均导致变量失效。

必须写在 :root 选择器内部,不能裸写在 CSS 文件顶层,否则浏览器直接忽略——这是变量不生效的最常见原因。
为什么只能用 :root,不能用 html 或 body
:root 是 CSS 规范指定的全局变量“锚点”,特异性为 0-1-0,比 html(0-0-1)更高,且在 SVG、XML 等非 HTML 文档中仍能匹配根元素。写成 html { --color: red; } 虽然多数情况能用,但在 Shadow DOM 边界、旧版 Safari 或多层嵌套组件中,变量可能无法可靠继承。
body { --color: red; } 更危险:变量只在 及其后代生效, 自身、表单控件(如 <input type="date"> 的内部 shadow tree)、或未被包裹的脚本插入元素,都读不到这个值。
- 别写
html:root(语法非法) - 别漏分号:一个声明缺分号(如
--size: 16px后没加分号),后续所有变量声明都会静默失效 - 变量名必须以
--开头,--text-color合法,-text-color或text-color无效
:root 块里变量怎么写才不报错也不 fallback
变量值必须是合法 CSS 值,单位不能分离,也不能在 calc() 外做运算。例如 --gap: 1rem 正确,--gap: 1 错误(缺单位);--shadow: 0 1px 2px rgba(0,0,0,0.1) 合法,但 --shadow-x: 0; --shadow-y: 1px; 再拼接使用会失败。
- 允许链式引用:
--size-lg: calc(var(--size-md) * 1.25),但禁止循环依赖(--a: var(--b); --b: var(--a)) - 嵌套引用最多两层:
var(--primary, var(--fallback, #333))可接受,三层以上可读性崩坏 - 所有主题下用到的变量,必须在默认
:root块中完整声明——哪怕深色模式值相同,也不能漏掉--shadow-sm这类变量,否则首屏渲染就 fallback 成transparent
引用 var() 时为什么颜色突然没了
var(--x) 不是函数调用,而是运行时向上查找最近的有效定义。失效几乎从不报错,而是静默回退到属性初始值或 inherited 值——比如 color: var(--text-color) 中 --text-color 拼错或未定义,文字可能变成透明或浏览器默认黑,极难排查。
- 务必写 fallback:
color: var(--text-color, #333),且 fallback 必须是该属性合法值(font-size: var(--size, red)会失效) - 大小写敏感:
--Text和--text是两个变量 - Shadow DOM 内部不会自动继承外部
:root变量,需在:host或::slotted中手动传入 - 设了
all: unset的元素会切断继承链,var()查找不到任何定义
最容易被忽略的是初始化时机:变量声明必须早于首屏样式计算,:root 块要放在 <style></style> 最顶部或独立 variables.css 的第一行;如果用 JS 动态注入 CSS,得确保它在 <link> 或 <style></style> 加载完成前执行,否则首屏闪白或主题错乱。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











