IE11及更早版本完全忽略var(--x)语法,整条CSS声明被静默丢弃;必须用postcss-custom-properties构建时降级,且需显式配置preserve:true、变量定义在:root、值为静态常量,并手动开启postcss-preset-env的custom-properties特性。

旧版浏览器(尤其是 IE11 及更早版本)根本不会解析 var(--x) 语法,不是“兼容性差”,而是整条声明被静默丢弃——连 fallback 值都不走。所以你看到背景透明、边框消失、布局塌陷,不是代码写错了,是浏览器压根没读那行 CSS。
IE11 里 var() 被完全忽略,必须静态替换
PostCSS 插件 postcss-custom-properties 是唯一靠谱的构建时降级方案,但它默认不生效,必须显式配置。关键点有三个:
-
preserve: true必须设 —— 否则输出只剩color: #007bff,新浏览器就失去动态能力;设为false或不写,旧浏览器能用,但主题切换、CSS-in-JS 就全废了 - 变量必须定义在
:root或显式作用域内 ——.card { --pad: 1rem; }这种局部定义,插件默认跳过,除非你配importFrom指向该文件 - 值必须是静态常量 ——
--size: calc(1rem + 2px)或--c: var(--base)这类无法静态求值的写法,插件原样保留,IE 看到就当无效声明扔掉
postcss-preset-env 默认不处理 CSS 变量
很多人以为装了 postcss-preset-env 就万事大吉,其实它默认只开 stage 3 特性,而 CSS 自定义属性属于 stage 2,必须手动打开:
postcss-preset-env({
stage: 3,
features: {
'custom-properties': true // 必须显式开启
}
})漏掉这行,postcss-custom-properties 根本不会运行,构建后 CSS 里还满屏 var(--x),旧浏览器当然全失效。
立即学习“前端免费学习笔记(深入)”;
calc() 里套 var() 在 IE11 中彻底不可用
width: calc(100% - var(--gap)) 这种写法,在 IE11 不是“var() 不生效”,而是整个 calc() 表达式被 parser 直接跳过。PostCSS 插件默认也不处理这种嵌套,因为无法安全求值。
- 不要指望
postcss-custom-properties+postcss-calc自动链式替换 —— 顺序错或配置漏,结果还是空值 - 稳妥做法:把
--gap: 12px这种纯数值变量,直接写成width: calc(100% - 12px) - 如果 gap 需动态,就得 JS 注入内联样式,或放弃 IE11 支持
兜底 class 比 @supports 更可靠
@supports (background: var(--x)) 在 IE11 里会报 TypeError,因为它根本不认识 @supports 规则。运行时检测也别用 CSS.supports('--x'),同样报错。
正确姿势是用 JS 检测后加 class:
if (window.CSS && CSS.supports('color', 'var(--test)')) {
document.documentElement.classList.remove('no-cssvars');
} else {
document.documentElement.classList.add('no-cssvars');
}然后在 CSS 里写:
.no-cssvars .btn { background: #007bff; }这个 class 必须在所有样式表加载前就存在,否则降级样式可能被覆盖 —— 很多人把 JS 放在 </body> 底部,导致闪屏或样式错乱。


















