sass、less 和 stylus 是 CSS 预处理器,它们通过引入变量、嵌套、混合宏(mixins)和函数等编程特性,扩展了原生 CSS 的能力,旨在解决样式复用和模块化管理的问题。其中,sass(特别是 SCSS 语法)是目前社区最主流的选择,拥有最广泛的生态支持;less 曾在早期流行,目前仍被部分旧项目使用;stylus 以语法简洁著称,但维护活跃度较低。postcss 则是一个不同的存在,它是一个 CSS 后处理工具链核心,本身不定义新语法,而是通过插件系统(如 autoprefixer、cssnano)对标准 CSS 进行转换、优化和修补。cssnano 是 postcss 生态中最著名的压缩优化插件。在现代架构中,通常采用“预处理器(如 Sass)+ 后处理器(PostCSS)”的组合方案,前者负责开发体验,后者负责兼容性与性能优化。
在前端架构设计中,CSS 的处理流程通常分为两个阶段:开发阶段(通过预处理器提升编写效率)和构建阶段(通过后处理器确保兼容性与性能)。sass、less、stylus 属于第一类,而 postcss 及其插件 cssnano 属于第二类。理解它们的定位差异,是构建高效样式工程体系的关键。
sass、less、stylus 的核心任务是**“发明新语法”**。它们允许你使用变量、嵌套、循环和条件判断来编写样式,最后编译成浏览器能读懂的标准 CSS。
postcss 的核心任务是**“处理标准 CSS”**。它本身不发明新语法,而是一个 JavaScript 工具链。它读取标准 CSS,通过插件系统对其进行修改(如添加前缀、压缩、转换新特性)。
// Sass: 定义变量和嵌套 (预处理)
$primary-color: #333;
.button {
color: $primary-color;
&:hover { opacity: 0.8; }
}
// PostCSS: 处理标准 CSS (后处理)
// 输入标准 CSS,通过 autoprefixer 插件自动添加前缀
.button {
display: flex;
/* 输出时自动变为: display: -webkit-flex; display: flex; */
}
虽然三者目标一致,但语法风格和实现机制有显著差异。
sass (SCSS 语法) 使用 $ 符号,这是目前最通用的标准。
// Sass (.scss)
$font-size-base: 16px;
body { font-size: $font-size-base; }
less 使用 @ 符号,这与 CSS 的 @media 或 @keyframes 容易在视觉上产生混淆。
// Less (.less)
@font-size-base: 16px;
body { font-size: @font-size-base; }
stylus 极其灵活,允许省略 $ 或 @,甚至省略冒号和分号,但这可能导致代码风格不统一。
// Stylus (.styl)
font-size-base = 16px
body
font-size font-size-base
三者都支持嵌套,但 stylus 对缩进敏感(类似 Python),而 sass (SCSS) 和 less 依赖大括号。
sass (SCSS) 结构清晰,大括号明确界定作用域。
// Sass
.nav {
ul { margin: 0; }
li { display: inline-block; }
}
less 语法与 SCSS 非常相似,迁移成本较低。
// Less
.nav {
ul { margin: 0; }
li { display: inline-block; }
}
stylus 依靠缩进,代码量最少,但重构时容易因缩进错误导致样式失效。
// Stylus
.nav
ul
margin 0
li
display inline-block
这是预处理器最强大的功能之一。
sass 支持强大的参数默认值和关键字参数。
// Sass
@mixin border-radius($radius: 4px) {
border-radius: $radius;
}
.box { @include border-radius($radius: 10px); }
less 支持类似功能,但关键字参数语法略有不同。
// Less
.border-radius(@radius: 4px) {
border-radius: @radius;
}
.box { .border-radius(@radius: 10px); }
stylus 语法最为简洁,甚至允许省略 @include 直接调用。
// Stylus
border-radius(radius = 4px)
border-radius radius
.box
border-radius(10px) // 直接调用
无论你选择哪种预处理器,编译出的 CSS 往往还需要进一步优化。这就是 postcss 和 cssnano 的战场。
原生 CSS3 属性(如 flex, grid)在旧浏览器中需要厂商前缀。预处理器通常不负责此事,这是 postcss (配合 autoprefixer) 的工作。
// postcss.config.js
module.exports = {
plugins: [
require('autoprefixer')({ overrideBrowserslist: ['last 2 versions'] })
]
};
输入标准 CSS:
.container { display: flex; }
PostCSS 输出(兼容旧浏览器):
.container { display: -webkit-box; display: -ms-flexbox; display: flex; }
cssnano 是 postcss 的插件,专门用于压缩 CSS。它不仅仅是删除空格,还会合并规则、优化选择器、移除重复声明。
// postcss.config.js (生产环境)
module.exports = {
plugins: [
require('cssnano')({
preset: 'default', // 启用默认优化集合
})
]
};
输入 CSS:
.box {
color: red;
margin: 10px 10px 10px 10px;
}
.box {
background: blue;
}
Cssnano 输出:
.box{background:blue;color:red;margin:10px} /* 合并规则,简写 margin,移除空格 */
在技术选型时,必须考虑包的长期维护性。
sass: 目前由 Dart 团队维护(Dart Sass),是官方推荐实现。旧版的 node-sass (基于 LibSass) 已正式弃用,新项目中严禁使用 node-sass,必须迁移至 sass。less: 仍在维护,但更新频率和社区活跃度明显低于 Sass。没有重大架构升级,处于“稳定但停滞”状态。stylus: 维护频率较低。虽然稳定,但面对现代 CSS 新特性(如原生嵌套、CSS 变量)的冲击,其独特语法的优势正在减弱。postcss & cssnano: 极度活跃。它们是 Webpack、Vite、Parcel 等现代构建工具的核心依赖,是事实上的行业标准。| 特性 | Sass (SCSS) | Less | Stylus | PostCSS (+cssnano) |
|---|---|---|---|---|
| 主要角色 | 预处理器 (语法扩展) | 预处理器 (语法扩展) | 预处理器 (语法扩展) | 后处理器 (工具链) |
| 变量符号 | $ | @ | 无/$ (可选) | N/A (处理标准 CSS) |
| 语法风格 | 类 CSS,需大括号 | 类 CSS,需大括号 | 简洁,缩进敏感 | N/A |
| 混合宏调用 | @include | .mixin-name() | 直接调用或 + | N/A |
| 逻辑控制 | 强大的 @if, @for | 基础支持 | 支持,语法独特 | 需通过 postcss-prettier 等插件或 JS 逻辑 |
| 兼容性处理 | 无 (需配合 PostCSS) | 无 (需配合 PostCSS) | 无 (需配合 PostCSS) | 核心功能 (Autoprefixer) |
| 压缩优化 | 无 (需配合 Cssnano) | 无 (需配合 Cssnano) | 无 (需配合 Cssnano) | 核心功能 (Cssnano) |
| 社区生态 | ⭐⭐⭐⭐⭐ (极大) | ⭐⭐⭐ (中等) | ⭐⭐ (较小) | ⭐⭐⭐⭐⭐ (基础设施) |
| 推荐指数 | 强烈推荐 | 仅用于旧项目 | 谨慎选择 | 必须使用 |
在现代前端工程体系中,不要将预处理器与后处理器对立起来,它们是互补的。
sass (Dart Sass) 作为开发语言,享受其成熟的生态和强大的编程能力;同时配置 postcss 链路,挂载 autoprefixer 处理兼容性,挂载 cssnano 处理生产压缩。node-sass,它已不再维护且安装困难。尽量避免为了“少写几个字符”而选择 stylus,因为原生 CSS 正在逐步吸纳其特性(如原生嵌套),独特的缩进语法反而增加了长期维护成本。sass 的逻辑处理能力依然不可替代。而 postcss 作为连接未来 CSS 特性与当前浏览器环境的桥梁,其地位只会更加稳固。当你需要减小生产环境 CSS 文件体积时,cssnano 是必选插件。它不应单独使用,而是作为 postcss 配置的一部分。如果你的构建流程中已经包含了 postcss,那么集成 cssnano 几乎是零成本的,它能自动移除无用代码、合并规则并优化选择器。
仅当你在维护一个已经深度依赖 Less 的遗留项目,或者团队对 Less 的特定功能(如 JavaScript 嵌入执行,尽管不推荐)有强依赖时才选择 less。对于新项目,由于其生态增长放缓且缺乏像 Dart Sass 那样的官方二进制分发优势,通常不建议作为首选。
任何现代前端项目都必须引入 postcss。无论你选择哪种预处理器,最终都需要通过 PostCSS 来处理浏览器前缀(autoprefixer)、CSS 语法降级(preset-env)以及生产环境压缩。它是连接现代 CSS 特性与浏览器实际支持能力的桥梁。
如果你的团队追求行业标准、需要最丰富的社区资源(如 Bootstrap、Tailwind 底层均基于 Sass),或者正在启动一个新的大型项目,sass 是首选。它的 SCSS 语法兼容原生 CSS,学习曲线平滑,且 Dart Sass 实现提供了极佳的稳定性和长期支持。
如果你的团队极度偏爱简洁语法(省略大括号和分号),且项目规模较小、对第三方 UI 库依赖较少,可以考虑 stylus。但在大多数企业级场景下,由于其社区活跃度下降及与主流设计系统(如 Material UI, AntD)的集成度不如 Sass,通常不作为推荐选项。
For documentation, please see the following links: