Sass/Less preprocessing phase
Preprocessor era
Sass / Less preprocessing stage
Sass and Less brought variables, nesting, and mixins into frontend engineering, solving the "plain CSS is too slow to write" problem for the first time at scale.
Variables and mixinsTheme customizationScripted compilation
Related packages
Ecosystem tools, libraries, and builder foundations referenced by this page.
Related solutions
Recommended follow-up chapters, supporting methods, and engineering landing points.
Key Points
- Variables/mix-ins/functions improve reusability, making BEM/OOCSS easier to implement; they are still in global scope.
- Nesting and inheritance can easily get out of control, and the compilation volume may expand; additional specifications are still required for design token alignment.
- Suitable for teams that have certain reuse needs but have not yet been componentized, or small and medium-sized projects that need to quickly implement themes.
- Representative packages:
Sass/SCSS(the strongest community,node-sass/dart-sasscompiler),Less(representative of theme variables in the Ant Design era),Stylus(flexible functional writing), and
Advantages / Disadvantages / When to use
| Item | Content |
|---|---|
| Advantages | Variables/mixins improve reuse; tool chain is mature; CSS output is controllable |
| Disadvantages | Still global pollution; nested hell; theme switching requires additional pipelines |
| Applicable | Small and medium-sized projects that require a small amount of theme switching or design draft mapping |
| Not applicable | Projects that require strong isolation/releasable component libraries and wish to align tokens directly |
Representative packages and common scenarios
- Sass/SCSS: The most complete mainstream functions, modularized with
@use/@forward. - Less: Classic usage of variable + calculated theme switching (Ant Design
modifyVars); still a global style. - Stylus: indentation syntax + functional mixin; common in early Vue templates.
- PostCSS plugin chain:
autoprefixer+postcss-nestingcombination to get new syntax support without migrating to CSS-in-JS.
Sass modular 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 quick theme switching
//Adjust modifyVars through webpack/vite
lessOptions: {
javascriptEnabled: true,
modifyVars: {
'@primary-color': '#111827',
'@btn-border-radius-base': '8px',
},
}
PostCSS plug-in chain (postcss.config.js)
module.exports = {
plugins: {
'postcss-nesting': {},
autoprefixer: {},
},
}
Example (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%); }
}
Common pitfalls and countermeasures
- Nesting levels: limited to 3 levels; prevent deep selectors via lint.
- Variable scattering: Concentrate tokens into a single file to prevent multiple swatches from splitting.
- Product size: avoid abusing
@extendand global mixins; check the compiled size regularly. - Migration path: Use CSS variables to carry tokens in advance to facilitate switching to Utility-first/componentization in the future.