必须设preserve: true,否则新浏览器无法响应主题切换、旧浏览器也得不到可靠降级;常见错误是配置失效或误用preserve: false,导致仅输出静态值而丢失var()声明,或因变量作用域、calc()嵌套、跨文件未引入等致替换失败。

必须设 preserve: true,否则新浏览器拿不到变量、旧浏览器也得不到可靠降级值。
为什么 postcss-custom-properties 编译后还留着 var(--x)
常见错误是配置了插件但没生效,或者误用了 preserve: false。这个选项控制的是“是否保留原始 var() 声明”——设成 false 就只输出静态值,现代浏览器完全无法响应主题切换或 JS 动态修改;设成 true(或干脆不写,默认就是 true)才会生成类似 color: #007bff; color: var(--primary); 这样的双声明。
其他原因还包括:
- 变量定义不在
:root或插件未配置的显式作用域内(比如写在.card { --pad: 1rem; }里,默认不处理) - 变量值含
calc()或嵌套var(--y),插件无法静态求值,原样保留 - 变量定义和使用不在同一文件,且没用
importFrom显式引入变量源
如何让局部变量也被正确替换
插件默认只分析 :root 和通过 importFrom 指定的变量源。若你坚持用组件级变量(如 .theme-dark { --color-text: #333; }),必须手动告诉插件哪些作用域要纳入处理:
立即学习“前端免费学习笔记(深入)”;
- 用
importFrom加载变量定义文件:importFrom: ['src/vars.css'] - 或直接传入变量对象:
variables: { '--color-text': '#333', '--spacing-xs': '4px' } - 确保变量名大小写完全一致,
--Color-Text和--color-text是两个变量
注意:插件不解析跨文件 @import 后的变量,除非你把 @import 写在被 importFrom 引用的文件里。
IE11 下 calc(var(--gap)) 为什么整个声明都失效
IE11 的 CSS 解析器遇到任何含 var() 的 calc() 表达式,会直接丢弃整条声明,连 fallback 都不走。这不是 PostCSS 漏转,而是浏览器层硬性限制。
可行解法只有两个方向:
- 提前算好值,避免运行时计算:
--gap: 12px→ 直接写width: calc(100% - 12px) - 用
postcss-calc插件配合postcss-custom-properties,但顺序必须是先custom-properties替换变量,再由calc处理数值运算
别指望 @supports (background: var(--x)) 在 IE11 生效——它根本不支持 @supports,兜底只能靠 JS 注入 no-cssvars 类 + 对应样式规则。
真正容易被忽略的是:构建后必须人工检查输出 CSS 文件里是否还有 var(-- 字符串。只要存在一个未被替换的 var(),就说明变量定义缺失、路径错位、或值不可静态解析——这种残留会在 IE11 里导致样式链断裂,不是颜色不对,而是整个声明被当空值处理。


















