stage参数是特性准入门槛而非功能开关:stage 0尝试解析实验语法但多无效,stage 2覆盖嵌套等激进特性,stage 3为最常用平衡点且polyfill稳定,stage 4仅含已发布标准故启用极少。

stage 参数不是功能开关,它只决定“哪些 CSS 特性有资格被考虑”,最终是否转译、怎么转译,还得看 browserslist 和 features 配置。
stage 值 0–4 对应什么实际效果
-
stage: 0:连@property这类实验语法都尝试解析,但多数无 polyfill,仅做语法通读;容易报错或编译后无效 -
stage: 2:覆盖嵌套规则(nesting-rules)、逻辑属性(logical-properties-and-values)、自定义媒体查询等,适合激进尝鲜 -
stage: 3:最常用平衡点,启用inset、font-variation-settings、custom-properties等,polyfill 较稳定 -
stage: 4:只包含已发布标准(如部分accent-color行为),实际启用特性极少,基本等于关掉大部分未来语法
注意:color-mix() 当前仍是 Stage 3,设 stage: 4 反而会把它排除——因为 Stage 4 是已发布标准,而它还没到那一步。
为什么设了 stage: 3 却没启用 @container
@container 属于 Stage 3,但 postcss-preset-env 默认不处理它:
- 它没有等价的静态 CSS 降级方案,必须靠运行时 JS 检测(如
@csstools/container-query-polyfill) - 即使写了
stage: 3,也得显式在features中打开:'container-queries': true - 启用后仍不会生成 fallback 样式,只是让语法通过解析;浏览器不支持就直接失效
常见错误现象:本地开发能看到容器查询效果,上线后 Safari 15.4 下断层 → 因为该版本对 container-type: inline-size 支持不完整,而 postcss-preset-env 不修复运行时语义差异。
stage 必须和 browserslist 配合才生效
-
stage决定“哪些特性可参与筛选”,browserslist才决定“哪些需要转译” - 没配
.browserslistrc或package.json中的browserslist字段,postcss-preset-env会退回到默认目标(通常是last 2 versions),但 stage 判断可能失准 - 示例配置(
.browserslistrc):> 1%<br>last 2 versions<br>not dead<br>ie 11
- 如果目标里包含 IE 11,
aspect-ratio就会被转译(哪怕它是 Stage 3);如果目标全是现代浏览器,它就原样保留——即使 Chrome 88–92 存在渲染 bug,postcss-preset-env也不管。
真正难的不是配 stage,而是搞清你写的那个特性:它有没有静态降级路径?目标浏览器到底支不支持?要不要额外引入 JS polyfill?这些都得一个个查 caniuse、CSSDB 和插件文档,不能只靠 stage 数字蒙眼开。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











