跳到主要内容

PostCSS

PostCSS 经常和 Less、SCSS、Autoprefixer 被放在一起说,最后很容易听起来像“又一个样式预处理器”。

其实不是。

PostCSS 更准确的定位是:

  • 一个处理 CSS 的平台
  • 一个把 CSS 解析成 AST,再交给插件加工的工具链
  • 一层样式编译和转换管道

所以它的关键点从来不在“自己提供了多少语法”,而在“能接什么插件、能做哪些转换”。

先看 PostCSS 在解决什么

PostCSS 最常见的价值一般落在这几类:

  • 自动补前缀
  • 使用未来 CSS 语法
  • 处理嵌套
  • 压缩 CSS
  • 规范化和转换写法
  • 给构建链提供统一的 CSS 处理入口

也就是说,PostCSS 更像一条加工链。

PostCSS 的工作方式怎么理解

官方架构文档里提到,PostCSS 会先把 CSS 字符串解析成 AST,再交给插件处理,最后再序列化回 CSS。

可以先记成这条线:

CSS -> Parser -> AST -> Plugins -> CSS

所以一个 PostCSS 配置,通常就是在描述:

  • 这份 CSS 要经过哪些插件
  • 每个插件分别做什么转换

它和预处理器不是一回事

这是最容易混的一点。

预处理器更偏“写法增强”

比如:

  • Less
  • SCSS
  • Stylus

它们更强调:

  • 变量
  • mixin
  • 嵌套
  • 循环
  • 函数

PostCSS 更偏“CSS 后处理”

比如:

  • Autoprefixer
  • postcss-preset-env
  • postcss-nesting
  • cssnano

它更关注:

  • 已经写出来的 CSS 怎么加工
  • 怎么转成更兼容的产物
  • 怎么让新语法更早用起来

所以真实项目里很常见的一条链路就是:

SCSS -> CSS -> PostCSS -> 浏览器

最常见的 PostCSS 插件

1. Autoprefixer

这大概是最普及的一类。

它会根据 Browserslist 目标,自动补厂商前缀。

.example {
user-select: none;
}

处理后可能会变成:

.example {
-webkit-user-select: none;
user-select: none;
}

现在很多构建链已经默认接了这层能力,但理解它仍然很重要,因为前缀不是“看到问题再补”,而是依赖目标浏览器范围统一生成。

2. postcss-preset-env

这一组插件很适合让项目提前使用一部分未来 CSS 语法。

比如:

  • 自定义媒体查询
  • 新的选择器能力
  • 一些草案阶段语法

它更像一个插件集合包,而不是单一功能插件。

3. postcss-nesting

这是现代 CSS 里非常常见的一类增强。

.card {
color: #111827;

& .title {
font-weight: 600;
}
}

如果项目不想上 SCSS,但又想保留嵌套表达,PostCSS 这条路会很顺。

4. cssnano

如果项目需要压缩 CSS,cssnano 是很典型的 PostCSS 体系插件。

5. postcss-import

这个插件可以把 @import 内联进构建流程里。像 Vite 就已经内建了这一层能力。

在前端项目里怎么集成

在 Vite 里

Vite 官方文档里提到,只要项目里存在可识别的 PostCSS 配置文件,就会自动应用到导入的 CSS 上。

安装最常见依赖

pnpm add -D postcss autoprefixer postcss-preset-env

postcss.config.mjs

export default {
plugins: {
autoprefixer: {},
'postcss-preset-env': {},
},
}

如果项目还要加嵌套:

pnpm add -D postcss-nesting
export default {
plugins: {
'postcss-nesting': {},
autoprefixer: {},
},
}

在 Vite 里的另一层理解

Vite 已经对 CSS 做了不少内建处理,包括:

  • @import 内联
  • URL rebasing
  • 预处理器接入
  • 自动读取 PostCSS 配置

所以在 Vite 里接 PostCSS,通常不需要额外折腾插件入口,更多是写好配置文件和插件顺序。

在 Next.js 里怎么接

Next.js 项目里接 PostCSS 也很常见,尤其是接 Tailwind 的时候。

基础配置

pnpm add -D postcss autoprefixer
// postcss.config.mjs
export default {
plugins: {
autoprefixer: {},
},
}

如果项目本身就用了 Tailwind,@tailwindcss/postcss 也会直接进这层配置。

一个更接近真实项目的配置参考

export default {
plugins: {
'postcss-nesting': {},
'postcss-preset-env': {
stage: 3,
features: {
'custom-properties': false,
},
},
autoprefixer: {},
},
}

这份配置的含义大致是:

  • 允许写嵌套
  • 允许一部分未来 CSS 语法
  • 自动补前缀
  • CSS 变量保留给浏览器原生处理

这类组合在现代项目里很常见。

插件顺序为什么重要

PostCSS 配置不能只是把插件全堆进去,顺序会直接影响结果。

比如:

  • 先做语法转换
  • 再做兼容处理
  • 最后再压缩

如果顺序乱了,某些插件可能拿不到它想处理的 AST 结构。

PostCSS 在真实项目里常见怎么用

1. 作为现代 CSS 增强层

不想引入 SCSS,但又想用:

  • nesting
  • 未来语法
  • 自动前缀

这时 PostCSS 很顺。

2. 作为 Tailwind 的处理链一部分

Tailwind 在很多项目里本身就是通过 PostCSS 接进构建链的。

3. 作为样式兼容和压缩入口

比如:

  • Autoprefixer
  • cssnano
  • preset-env

PostCSS 的优点

  • 插件生态强
  • 和构建工具结合自然
  • 很适合现代 CSS 渐进增强
  • 不强制换掉原生 CSS 写法

PostCSS 的局限

  • 本身不是完整语法方案
  • 插件选得太多时,配置会变复杂
  • 插件顺序和能力边界需要理解
  • 有些问题更适合直接靠现代 CSS 解决,而不是继续堆插件

PostCSS 和 Tailwind 的关系

Tailwind 经常通过 PostCSS 链路接入,所以很多人第一次真正接触 PostCSS,其实就是在配 Tailwind。

但要分清这两层:

  • Tailwind:设计 token 和 utility classes
  • PostCSS:CSS 加工和转换链路

PostCSS 和 CSS Modules 的关系

它们也不是替代关系。

  • CSS Modules:解决作用域
  • PostCSS:解决加工链路

项目里完全可以同时存在:

  • .module.css
  • postcss.config.mjs
  • autoprefixer
  • postcss-nesting

什么时候值得优先考虑 PostCSS

  • 想尽量用现代原生 CSS
  • 只缺少少量语法增强和兼容处理
  • 项目已经在走 Tailwind / Vite / Next 这类现代构建链
  • 需要统一的 CSS 插件入口

一个更实际的判断

PostCSS 不一定要被理解成“必须手写很多复杂配置”的工具。对大多数项目来说,更常见的用法其实是:

  • 接 Autoprefixer
  • 视情况加 nesting
  • 视情况加 preset-env

先把这几层用稳,已经能覆盖大量真实场景。

参考来源