stage 参数是特性准入门槛而非开关,设为3表示仅考虑W3C候选推荐及以上成熟度的CSS特性,并需配合browserslist和features手动启用如@container、:has()等特定功能。

stage 参数不是开关,是特性准入门槛
设 stage: 3 并不等于“开启所有 Stage 3 特性”,而是告诉 postcss-preset-env:只考虑成熟度 ≥ Stage 3(W3C 候选推荐)的特性,再结合 browserslist 和实际 CSS 内容做二次判断。比如 color-mix() 是 Stage 3,但 @container 是 Stage 3 末期、部分语义尚未稳定,它默认不会启用——除非你手动在 features 里打开。
常见误操作:
- 把 stage: 0 当“全开模式”,结果 @property 这类无 polyfill 的实验语法被解析但无输出,构建不报错、运行无效
- 单独调低 stage 却不配 browserslist,导致 nesting-rules 编译后仍是原样,IE11 直接忽略整个规则块
- 以为 stage: 4 更“先进”,其实它几乎不启用任何新语法,因为真正进入 Stage 4 的 CSS 特性极少(如部分 accent-color 行为)
stage: 3 是最稳妥的起点,但必须配合 targets 或 browserslist
stage 自身不决定是否转译,最终行为由目标环境驱动。即使写了 stage: 3,若 browserslist 里没写 ie 11,那 inset、logical-properties-and-values 就不会加前缀或降级;若只写 last 2 versions,而你本地 Chrome 是 124,那 :has() 就直接保留,不转译。
实操建议:
- 在项目根目录放 .browserslistrc,内容示例:> 0.5%, last 2 versions, not dead, ie 11
- 非 Webpack 场景(如 PostCSS CLI 或 Vite 插件),建议显式传 targets:{ chrome: '45', ie: '11', safari: '10' },避免读取不到配置
- 不要依赖 postcss-preset-env 内置的 autoprefixer 行为,它和独立 autoprefixer 插件顺序冲突,应关闭内置前缀:autoprefixer: false
想用 @container、:has() 这类特性,features 配置不能省
@container、:has()、color-mix() 等虽在 cssdb 标记为 Stage 3,但 postcss-preset-env 默认不处理它们——因为它们要么无静态等价语法(@container),要么依赖运行时支持(:has() 在 Safari 15.4+ 才稳定)。不显式启用,写了也白写。
正确写法示例:
require('postcss-preset-env')({<br> stage: 3,<br> features: {<br> 'container-query': true,<br> 'has-pseudo-class': true,<br> 'color-mix-function': true<br> }<br>})注意:
-
container-query 启用后,仅保留语法合法性检查,不生成 JS polyfill,需额外引入 container-query-polyfill-
color-mix-function 在旧浏览器中不会 fallback 到预设色值,必须手写 background-color: #000; background-color: color-mix(...);-
has-pseudo-class 转译后是 JavaScript 检测 + class 注入,不是纯 CSS 替代,性能敏感场景慎用
CSS 变量、clamp()、aspect-ratio 这些不能靠 preset-env 降级
postcss-preset-env 不解析变量值,也不生成 @supports 回退逻辑。写了 background-color: var(--primary),IE11 依然白屏;写了 width: clamp(10rem, 50%, 30rem),老浏览器直接忽略整条声明。
立即学习“前端免费学习笔记(深入)”;
必须手动兜底:
- CSS 变量:始终写两遍,先静态值再 var(),靠层叠覆盖:color: #333; color: var(--text-color);
- clamp() 和 aspect-ratio:用 @supports (clamp: 0) {} 包裹新语法,并在外部写传统方案(如 padding-top 百分比 hack)
- postcss-custom-properties 插件可内联变量,但需设 preserve: false,且对 JS 动态注入的变量完全无效
- 所有 fallback 必须经真机测试,自动化检查工具(如 stylelint-no-unsupported-browser-features)只能帮到语法层


















