PostCSS-preset-env 是一个基于标准阶段和目标浏览器的 CSS 新特性转译插件,仅处理已有规范依据的 Stage 2+ 特性,按 browserslist 决定是否转译、加前缀或保留原样,不支持实验语法或运行时模拟。
它不是魔法,而是一个「特性开关+降级编译」的组合插件。你写 color-mix()、:has()、aspect-ratio 这类新语法,它会根据你配置的目标浏览器(browserslist),决定是否转译、怎么转译、甚至干脆不处理——前提是该特性已在目标环境原生支持。
关键判断点:它只做「有标准依据」且「已有草案或已进入候选推荐」的特性,不会实现 Stage 0 的实验语法(比如某些 CSS Houdini API)。别指望它把 @container 编译成 JS 媒体查询模拟,它只在浏览器已支持但需加前缀时补前缀,或对部分特性(如 nesting)提供有限降级。
必须确保你的构建流程已启用 PostCSS(如 webpack 的 postcss-loader、Vite 的内置支持、或 CLI 工具),否则 postcss-preset-env 就是空转。
npm install postcss-preset-env --save-dev
postcss.config.js 中启用(不是单独 import,而是作为 plugin 调用):module.exports = { plugins: [ require('postcss-preset-env')({ stage: 3, features: { 'nesting-rules': true, 'custom-properties': true } }) ]}
.browserslistrc(或 package.json 中的 browserslist 字段),例如:> 1%last 2 versionsnot dead否则
stage 和 features 的生效范围无法推导stage 控制的是「语言特性成熟度门槛」,不是功能开关。Stage 3 表示已进入 W3C 候选推荐(CR),基本稳定;Stage 2 是工作草案(WD),可能微调;Stage 4 是已发布标准。设为 stage: 2 并不意味着自动开启所有 Stage 2 特性——它只是放宽准入条件,具体是否启用仍取决于 features 显式声明或浏览器兼容表。
立即学习“前端免费学习笔记(深入)”;
常见易错点:
stage: 4 却发现 color-mix() 没编译?因为该函数目前仍是 Stage 3,stage: 4 反而把它过滤掉了'nesting-rules': true 后,& .child 写法被转成 .parent .child,但嵌套中的 &:hover 不会自动提升选择器权重,原始语义仍受限'custom-properties': { preserve: false } 会让自定义属性直接内联展开,但若变量依赖运行时 JS 修改,则编译后失效——这不是 bug,是设计使然它不处理运行时逻辑、不模拟缺失的渲染能力、也不填补 DOM/CSSOM API 缺口。以下情况它完全不介入:
@container 查询:当前仅 Chromium 支持,postcss-preset-env 不提供 polyfill 或 JS fallback,需搭配 container-query-polyfill 等独立库scroll-driven animations(@keyframes + scroll()):无对应编译路径,只能降级为 JS 动画库(如 GSAP)subgrid:虽已进 Stage 3,但因实现复杂度高,postcss-preset-env 目前不提供降级方案,IE/旧 Safari 用户仍需用常规 grid 模拟布局aspect-ratio 的容器尺寸监听):编译后只是静态值,动态适配得靠 ResizeObserver
最常被忽略的一点:它只作用于 CSS 源码文本转换,不改变浏览器解析优先级或层叠规则。写错的 :has() 选择器即使被保留下来,在不支持的浏览器里依然报无效,得靠 @supports 或 JS 特性检测兜底。