var()的第二个参数是回退值而非兜底终点,仅在变量完全未声明或被设为unset/initial时生效;若已声明为空字符串、非法值等则不触发,且回退值本身可嵌套var()形成链式降级。

var() 的默认值不是兜底,而是新一轮查找
写 var(--color, #000) 时,#000 不是“最终 fallback”,而是一次新的变量求值起点。如果这个默认值本身又是 var(--fallback, #333),浏览器会继续尝试解析 --fallback——它仍可能未定义、拼错、或被 unset 覆盖。
这意味着:你看到颜色没变,未必是 --color 没定义,更可能是 --fallback 也不存在,最终落到 color: inherit 或初始值上。
- 只有变量**完全未声明**(即整个样式表里搜不到
--color:这种赋值),才会触发默认值 - 变量声明了但值非法(如
--color: 123)时,部分浏览器仍尝试解析,不一定走默认值 - 变量被显式设为
unset或initial,也会导致 var() 回退到默认值 - 调试时直接看 DevTools 的 Computed 面板,比翻 CSS 源码更快定位哪一级掉链子
Chrome DevTools 怎么快速确认变量是否真未定义
浏览器从不报错,但计算值会暴露真相。打开 Elements → Styles,找到含 var(--x) 的那行声明:
- 若右侧显示
color: initial或color: inherit(且没写 fallback),基本可断定--x在当前作用域链中未声明 - 点击该属性名,DevTools 会高亮所有匹配的定义位置(
:root、.theme-dark等),帮你确认是不是漏写了或作用域没覆盖到 - 注意大小写:
--Red≠--red,CSS 变量严格区分大小写 - 动态插入的
<style></style>必须在引用它的规则之前执行,否则 DOM 解析顺序会导致“定义滞后”
JavaScript 读取未定义变量返回空字符串,不是 undefined
用 getComputedStyle(el).getPropertyValue('--size') 得到 "",不代表变量“未定义”——它也可能被显式设为空字符串 el.style.setProperty('--size', '')。两者行为一致,无法靠返回值区分。
立即学习“前端免费学习笔记(深入)”;
-
getComputedStyle只读全局生效的变量(来自:root或已匹配的选择器),若变量定义在.dark-mode --x但元素没加dark-mode类,结果就是"" -
element.style.getPropertyValue()只读内联样式,完全不感知 CSS 文件里的定义 - 执行时机很关键:脚本运行时 DOM 未就绪、CSS 尚未加载完,都会导致读到
"";建议包裹在DOMContentLoaded或requestAnimationFrame中 - 频繁调用
getComputedStyle会强制重排,滚动中读未定义变量可能放大卡顿
PostCSS 构建时检查只能捕获静态引用
像 postcss-custom-properties 这类插件,只扫描同一文件内、已写出的 :root { --x: red } 这类静态定义。它对这些情况完全无感:
- 变量通过
document.documentElement.style.setProperty('--x', 'red')运行时注入 - 变量定义在另一个未被 PostCSS 处理的 CSS 文件中(比如第三方库的 CSS)
- 变量名动态拼接:
var(--theme-${mode}),构建时根本无法推导出mode值
真正难防的是这种场景:你写了 var(--primary, var(--fallback)),而 --fallback 又依赖 JS 初始化——构建时一切正常,上线后 JS 失败,整个链就断了。这时候只能靠运行时断点 + getComputedStyle 手动验证。


















