IE11完全不识别var(--x)语法,整条CSS声明被静默丢弃;后备值var(--x, #fff)无效,因IE连var()函数都解析不了;必须前置静态值、后置var()覆盖,并配合@supports隔离现代逻辑或postcss-custom-properties设preserve:false静态替换。

IE11完全不识别var(--x)语法,所有含CSS变量的声明都会被静默丢弃——不是降级,是整行失效。靠var(--x, #fff)根本救不了,它连var()函数都解析不了。
IE11里CSS变量为什么连后备值都不生效
这是最典型的误判:以为var(--primary, #007bff)能在IE里 fallback 到#007bff。实际上,IE11遇到color: var(--primary, #007bff),直接判定整条规则无效,跳过执行,最终取继承值或初始值(比如color变成黑色)。
-
var(--x, ...)的后备机制只在支持CSS变量的浏览器中起作用(Chrome 49+、Firefox 31+、Safari 9.1+) - 后备值不能是另一个
var(),也不能是initial或unset,IE里全无效 - 哪怕你写了
color: #212529; color: var(--bs-body-color);,IE也只认第一行,第二行被忽略——但这是唯一可行的兜底路径
正确写法:静态值前置 + @supports包裹现代逻辑
必须把兼容性兜底写在前面,让IE优先读到;再用@supports把变量逻辑隔离在现代浏览器中执行。
- 顺序不可颠倒:
background: #007bff; background: var(--primary, #007bff); -
@supports检测必须用「使用行为」,不是「定义行为」:@supports (color: var(--_))(变量名任意,甚至不存在) -
@supports (--x: red)是非法语法,所有浏览器都会忽略 -
@supports本身IE11也不支持,所以它只能用于增强,不能替代静态兜底
button {
background: #007bff; /* 所有浏览器都认 */
}
@supports (background: var(--bg)) {
button {
background: var(--bg, #007bff); /* 仅现代浏览器启用 */
}
}构建时降级:用postcss-custom-properties但必须关掉preserve
PostCSS插件不是“自动兼容”,默认配置下它只做替换不删原句,结果IE看到color: #007bff; color: var(--primary);,仍会跳过第二行——样式照样丢失。
立即学习“前端免费学习笔记(深入)”;
- 必须设
preserve: false,插件才会真正移除var()调用,只留降级值 - 变量定义必须在
:root或显式声明的作用域内;局部作用域(如.card { --pad: 1rem; })默认不处理 - 值必须是静态常量:
--size: calc(1rem + 2px)或嵌套var(--b)无法求值,原样保留,IE照样报错 - Webpack + CSS Modules项目中,类名哈希会破坏插件对选择器的识别,建议全局变量统一写在
:root
运行时兜底:JS检测 + class切换比CSS.supports()更可靠
CSS.supports('--x')在IE11会直接抛TypeError,因为参数格式非法;而@supports规则本身IE也不支持,纯CSS方案必须靠class驱动。
- JS里正确检测方式:
CSS.supports('color', 'var(--theme-color)') - 关键样式应由class控制,比如给
<html>加no-cssvars类,再写.no-cssvars .btn { background: #007bff; } - Bootstrap 5+大量依赖
--bs-primary等变量,IE11里color: var(--bs-body-color)等于没写,文字可能直接变黑消失——必须靠class兜底覆盖
真正麻烦的不是怎么写降级代码,而是IE11对同一段CSS的盒模型计算和渲染路径与现代浏览器完全不同。哪怕你把所有var()都替掉了,flex容器里子元素的高度、padding、border-radius表现仍可能差一两个像素——必须用真实IE11环境逐层inspect,模拟器和polyfill糊弄不过去。


















