必须设preserve:false,否则IE11及更早版本会静默丢弃含var()的整条CSS声明,导致样式消失;该配置确保构建时彻底删除var()行、仅保留静态值,避免因双声明或动态变量引发兼容性失效。

必须设 preserve: false,否则 IE11 及更早版本会静默丢弃整条含 var() 的声明——不是颜色没变,而是样式直接消失。
为什么 preserve: false 是硬性要求
默认配置下,postcss-custom-properties 只追加降级值,生成类似这样的输出:
background: #007bff; background: var(--primary);
IE 解析到第二行就跳过,最终取初始值(比如透明背景、黑色文字),大面积样式丢失。只有 preserve: false 才会真正删掉含 var() 的行,只保留静态值。
-
preserve: true或不写该选项 → 构建后仍有var(--x),IE 依旧失效 - 若同时用
css-vars-ponyfill,它依赖原始var()存在;此时必须配preserve: true,但 IE 下会双失效 - Webpack/Vite 中需确认插件顺序:
postcss-custom-properties必须在autoprefixer之前
变量定义必须满足三个静态约束
PostCSS 插件是编译期工具,它看不到 JS 动态设置、跨文件定义、或运行时计算的值。所有能被降级的变量,必须满足:
立即学习“前端免费学习笔记(深入)”;
- 声明在
:root最稳妥;.card { --pad: 1rem; }这类局部定义默认不处理,除非显式配importFrom指向该文件 - 值只能是纯常量:
--color: red;✅,--size: calc(1rem + 2px);❌,--c: var(--base);❌ - 媒体查询内定义的变量(如
@media (min-width: 768px) { :root { --gap: 16px; } })通常无法被回溯解析,建议提至顶层
calc() 里嵌套 var() 怎么办
width: calc(100% - var(--gap)); 在 IE11 中不是 “var() 不生效”,而是整个 calc() 表达式被 parser 直接跳过——连数值都不算。PostCSS 插件默认不处理这种嵌套,因为它无法安全求值。
- 稳妥做法:把
--gap: 12px这种纯数值变量,直接写成width: calc(100% - 12px); - 如果
--gap需动态变化,就得 JS 注入style属性,或明确放弃 IE11 支持 - 别指望
postcss-calc和postcss-custom-properties链式工作——顺序错或配置漏,结果仍是空值
兜底 class 比 @supports 更可靠
@supports (background: var(--x)) 在 IE11 里本身不被识别,会直接忽略整条规则。它只能用于现代浏览器的增强逻辑,不能单独作为降级依据。
- 正确做法是前置静态值、后置
var()覆盖:background: #007bff; background: var(--primary);,顺序不能颠倒 - 推荐用
no-cssvars类强制切换降级样式,比如在<html class="no-cssvars">下启用整套静态主题 - CSS 压缩工具(如
cssnano)若开了discardDuplicates,可能把重复的color声明删掉——要关掉这个选项
最容易被忽略的是:变量必须在构建时就“可确定”,JS 动态注入的 setProperty、跨文件定义、拼写错误的引用,都会让插件完全无感,最终输出的 CSS 里仍残留 var(),导致 IE 崩溃。


















