IE11 不识别 var() 函数,遇含 var() 的 CSS 声明会整行静默丢弃,连后备值也不解析;必须前置静态值(如 color: #333; color: var(--text, #333))并配合 preserve: false 等配置确保降级生效。

IE11 里 var() 不是“不生效”,而是整条 CSS 声明被静默丢弃——连后备值都进不了解析器。想让页面基础可用,必须让 IE 看到的是纯静态 CSS,且静态值要写在 var() 前面、同一属性名下。
为什么 color: var(--text, #333) 在 IE11 中完全无效
IE11 根本不认识 var() 这个函数名,遇到 color: var(--text, #333) 就当语法错误跳过整行。它不会尝试解析括号内容,也不会 fallback 到 #333。结果就是 color 取继承值(常为黑色)或 initial(比如 background 变成 transparent)。
- ✅ 正确姿势:
color: #333; color: var(--text-color, #333);—— IE 执行第一行,现代浏览器覆盖第二行 - ❌ 错误写法:
color: var(--text-color, #333);或color: #333; margin: var(--gap);(不同属性名无法覆盖) - ⚠️ 复合属性如
background、border含var()时,IE 会丢弃整条声明,背景/边框直接消失
postcss-custom-properties 必须设 preserve: false
默认配置下该插件只追加降级值,比如把 color: var(--primary); 编译成:
color: #007bff; color: var(--primary);
IE 仍会跳过第二行,最终样式不可控。只有显式设 preserve: false,插件才会删掉所有含 var() 的行,只保留静态值。
立即学习“前端免费学习笔记(深入)”;
- Webpack/Vite 中,确保该插件在
autoprefixer之前运行,否则可能被覆盖 - 若同时用
css-vars-ponyfill,就不能设preserve: false—— ponyfill 需要原始var()才能运行时注入,此时得靠 JS 检测 +no-cssvars类兜底 - 变量必须定义在
:root,且值为静态常量:--color: red;✅,--size: calc(1rem + 2px);❌,--c: var(--base);❌
@supports (color: var(--_)) 不能单独用于 IE 降级
@supports 本身在 IE11 中不被识别,整条规则会被忽略。它只能包裹增强逻辑(比如 grid 布局),不能替代静态兜底。
- ✅ 可用检测方式:
CSS.supports('color', 'var(--t)')(传完整声明字符串,IE 不报错) - ❌ 错误检测:
CSS.supports('--t')(IE 报TypeError) - 更稳妥的兜底是给
加类:,再用.no-cssvars .btn { background: #007bff; }写降级样式 - 媒体查询内定义的变量(如
@media (min-width: 768px) { :root { --gap: 16px; } })通常无法被 PostCSS 回溯解析,建议提至顶层
calc() 里嵌套 var() 在 IE11 中无解
width: calc(100% - var(--gap)); 在 IE11 中不是 “var() 不生效”,而是整个 calc() 表达式被 parser 直接跳过。PostCSS 插件默认不处理这种嵌套,因为它无法安全求值。
- ✅ 稳妥做法:把
--gap定义为纯数值(如--gap: 12px;),然后写成width: calc(100% - 12px); - ⚠️ 若
--gap需动态变化(如响应式),就得用 JS 注入内联样式,或直接放弃 IE11 支持 - 别指望
postcss-calc和postcss-custom-properties链式工作——顺序错或配置漏,结果仍是空值
真正容易被忽略的是:变量是否“已声明但为空”。getComputedStyle(el).getPropertyValue('--foo') 返回 ""(空字符串)表示已声明但值为空,返回 null 才是未定义;而回退值只对 null 生效。所以不要在 :root 里初始化 --x: "",这会让 var(--x, #000) 拿到空字符串,样式直接崩。


















