Sass / Less 预处理阶段
要点
- 变量/混入/函数提升复用度,BEM/OOCSS 更易落地;仍是全局作用域。
- 嵌套与继承易失控,编译体积可能膨胀;设计 token 对齐仍需额外规范。
- 适合有一定复用需求但尚未组件化的团队,或需快速落地主题的中小项目。
- 代表性包:
Sass/SCSS(社区最强,node-sass/dart-sass编译器)、Less(Ant Design 时代的主题变量代表)、Stylus(函数式写法灵活)、PostCSS(通过插件完成 autoprefixer、nesting)。
优势 / 劣势 / 何时使用
| 项 | 内容 |
|---|---|
| 优势 | 变量/混入提升复用;工具链成熟;CSS 输出可控 |
| 劣势 | 仍是全局污染;嵌套地狱;主题切换需额外管线 |
| 适用 | 中小型项目、需要少量主题切换或设计稿映射 |
| 不适用 | 需要强隔离/可发布组件库、希望直接对齐 tokens 的项目 |
代表性包与常见场景
- Sass/SCSS:主流功能最全,配合
@use/@forward进行模块化。 - Less:变量 + 计算的主题切换(Ant Design
modifyVars)经典用法;仍然是全局样式。 - Stylus:缩进语法 + 函数式 mixin;在 Vue 早期模板中常见。
- PostCSS 插件链:
autoprefixer+postcss-nesting组合,在不迁移到 CSS-in-JS 的情况下获得新语法支持。
Sass 模块化 tokens
// tokens/_color.scss
$primary: #111827;
$muted: #6b7280;
// tokens/_radius.scss
$card-radius: 16px;
// styles/card.scss
@use '../tokens/color' as *;
@use '../tokens/radius' as *;
.card {
border: 1px solid lighten($primary, 65%);
border-radius: $card-radius;
}
Less modifyVars 快速主题切换
// 通过 webpack/vite 调整 modifyVars
lessOptions: {
javascriptEnabled: true,
modifyVars: {
'@primary-color': '#111827',
'@btn-border-radius-base': '8px',
},
}
PostCSS 插件链 (postcss.config.js)
module.exports = {
plugins: {
'postcss-nesting': {},
autoprefixer: {},
},
}
示例(Sass + BEM)
$radius: 16px;
$primary: #111827;
$muted: #6b7280;
.card {
border: 1px solid lighten($primary, 65%);
border-radius: $radius;
padding: 16px;
&--elevated { box-shadow: 0 10px 30px rgba(0, 0, 0, 0.06); }
&__header { display: flex; flex-direction: column; gap: 8px; }
}
.eyebrow { font-size: 12px; letter-spacing: 0.1em; color: $muted; }
.btn {
padding: 10px 16px;
border-radius: $radius - 4px;
border: 1px solid $primary;
background: $primary;
color: #fff;
&:hover { background: darken($primary, 5%); }
}
常见坑与对策
- 嵌套层级:限制在 3 层以内;通过 lint 阻止深层选择器。
- 变量散落:集中 tokens 到单一文件,防止多处色板分叉。
- 产物体积:避免滥用
@extend与全局混入;定期检查编译后大小。 - 迁移路径:提前用 CSS 变量承载 tokens,便于未来切到 Utility-first/组件化。
