IE11及更早版本完全不解析var(--x),整条CSS声明被静默丢弃,导致样式彻底丢失;var(--x,#fff)无效,因IE连var()语法都不识别,必须前置静态值并配合postcss-custom-properties设preserve:false进行构建时替换。

IE11 及更早版本遇到 var(--x) 会直接跳过整条 CSS 声明,不是“颜色没变”,而是样式彻底丢失——按钮透明、文字变黑、边框消失都是典型表现。靠 var(--x, #fff) 无法兜底,必须用静态值前置 + 构建时替换双保险。
为什么 var(--x, #fff) 在 IE11 里完全无效
IE11 根本不识别 var() 函数语法,连括号里的内容都不会解析。它看到 color: var(--text, #333); 就当整行不存在,最终取继承色或属性初始值(比如 background 变成 transparent)。这不是 fallback 失效,是声明被丢弃。
- 后备值只在支持 CSS 变量的浏览器中起作用(Chrome 49+、Firefox 31+、Safari 9.1+)
-
var(--a, var(--b, #000))这种嵌套在 IE 里连最外层都不认 - 写成两行
color: #333;换行再写color: var(--text);同样不行——IE 跳过第二行,但第一行能生效;可一旦顺序颠倒,就全废
必须用“静态值前置 + var() 覆盖”的写法
让 IE 读第一行,现代浏览器用第二行覆盖,这是唯一可靠的手动降级模式。
- 顺序不可调换:
background-color: #007bff;必须在前,background-color: var(--primary, #007bff);紧随其后 - 简写属性(如
background、border、font)必须拆成原子属性,每条都加静态值:background-color: #fff;和background-color: var(--bg, #fff);分开写 - 单位必须一致:
--gap: 12px;的 fallback 就得是12px,不能写12 - 所有变量定义必须集中在
:root,局部定义(如.card { --pad: 1rem; })IE 看不到,PostCSS 也难处理
postcss-custom-properties 的配置关键点
这个插件不是装上就自动工作,它只在构建时做静态替换,且对输入格式极其敏感。
立即学习“前端免费学习笔记(深入)”;
- 必须设
preserve: false:否则输出background: #007bff; background: var(--primary);,IE 仍会跳过第二行导致样式断裂 - 变量值只能是纯常量:
--size: calc(1rem + 2px)或--c: var(--base)会被跳过,留下未替换的var() - Webpack/Vite 中,插件必须在
autoprefixer之前运行,否则可能被覆盖或干扰 - 如果用了
css-vars-ponyfill,就不能设preserve: false——两者逻辑冲突,会导致双失效
运行时检测别信 @supports,用 no-cssvars 类更稳
@supports (background: var(--x)) 在 IE11 里本身就不被识别,整条规则包括里面的内容都会被忽略,不能作为降级依据。
- 正确做法是 JS 检测后给
<html>加类:document.documentElement.classList.add('no-cssvars'); - 然后写两套规则:
.btn { background: var(--primary); }和.no-cssvars .btn { background: #007bff; } -
CSS.supports('--x')在 IE 里会报TypeError,必须传完整声明字符串:CSS.supports('color', 'var(--_)') - 媒体查询内定义的变量(如
@media (min-width: 768px) { :root { --gap: 16px; } })PostCSS 通常无法回溯,建议全部提至顶层:root
真正容易被忽略的是:变量定义位置和构建链路的耦合性。哪怕 SCSS 里写了 @include theme() 并在里面用了 var(--x),SCSS 编译器也完全不处理它——最终能否降级,只取决于 PostCSS 是否能在 CSS 输出阶段找到对应静态定义。漏掉任何一个环节,IE 就只剩白屏或黑字。


















