CSS 预处理器对比

Sass、Less、Stylus 的语法差异与选型建议

问题

Sass、Less、Stylus 三种 CSS 预处理器有什么区别?各自的优缺点是什么?

解答

基本信息

特性SassLessStylus
诞生时间200620092010
实现语言Dart (原 Ruby)JavaScriptJavaScript
文件扩展名.scss / .sass.less.styl

语法对比

1. 变量定义

/* Sass - 使用 $ 符号 */
$primary-color: #3498db;
$font-size: 16px;

.button {
  color: $primary-color;
  font-size: $font-size;
}
/* Less - 使用 @ 符号 */
@primary-color: #3498db;
@font-size: 16px;

.button {
  color: @primary-color;
  font-size: @font-size;
}
/* Stylus - 无需特殊符号,可省略冒号和分号 */
primary-color = #3498db
font-size = 16px

.button
  color primary-color
  font-size font-size

2. 嵌套规则

/* Sass */
.nav {
  ul {
    margin: 0;
    li {
      display: inline-block;
      a {
        text-decoration: none;
        &:hover {  /* & 引用父选择器 */
          color: red;
        }
      }
    }
  }
}
/* Less - 语法与 Sass 基本一致 */
.nav {
  ul {
    margin: 0;
    li {
      display: inline-block;
      a {
        text-decoration: none;
        &:hover {
          color: red;
        }
      }
    }
  }
}
/* Stylus - 可省略花括号,用缩进表示层级 */
.nav
  ul
    margin 0
    li
      display inline-block
      a
        text-decoration none
        &:hover
          color red

3. Mixin(混合)

/* Sass - 使用 @mixin 和 @include */
@mixin flex-center($direction: row) {
  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: $direction;
}

.container {
  @include flex-center(column);
}
/* Less - 直接用类名作为 mixin */
.flex-center(@direction: row) {
  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: @direction;
}

.container {
  .flex-center(column);
}
/* Stylus - 定义方式更灵活 */
flex-center(direction = row)
  display flex
  justify-content center
  align-items center
  flex-direction direction

.container
  flex-center(column)

4. 条件与循环

/* Sass - 完整的控制流语法 */
@for $i from 1 through 3 {
  .col-#{$i} {
    width: percentage($i / 12);
  }
}

@mixin theme($dark: false) {
  @if $dark {
    background: #333;
    color: #fff;
  } @else {
    background: #fff;
    color: #333;
  }
}
/* Less - 使用递归模拟循环 */
.generate-columns(@n, @i: 1) when (@i =< @n) {
  .col-@{i} {
    width: percentage(@i / 12);
  }
  .generate-columns(@n, (@i + 1));
}
.generate-columns(3);

/* 条件使用 when 守卫 */
.theme(@dark) when (@dark = true) {
  background: #333;
  color: #fff;
}
.theme(@dark) when (@dark = false) {
  background: #fff;
  color: #333;
}
/* Stylus - 语法最接近编程语言 */
for i in 1..3
  .col-{i}
    width (i / 12 * 100)%

theme(dark)
  if dark
    background #333
    color #fff
  else
    background #fff
    color #333

5. 函数

/* Sass - 内置函数丰富 */
$base-color: #3498db;

.element {
  color: darken($base-color, 10%);      // 加深
  background: lighten($base-color, 20%); // 变浅
  border-color: rgba($base-color, 0.5);  // 透明度
}

/* 自定义函数 */
@function calculate-rem($px) {
  @return $px / 16px * 1rem;
}

.text {
  font-size: calculate-rem(24px); // 1.5rem
}
/* Less - 函数语法类似 */
@base-color: #3498db;

.element {
  color: darken(@base-color, 10%);
  background: lighten(@base-color, 20%);
  border-color: fade(@base-color, 50%);
}
/* Stylus - 函数定义更自由 */
base-color = #3498db

calculate-rem(px)
  px / 16px * 1rem

.element
  color darken(base-color, 10%)
  background lighten(base-color, 20%)
  
.text
  font-size calculate-rem(24px)

优缺点对比

Sass

优点:

  • 功能最完善,社区最大
  • 两种语法可选(SCSS 兼容 CSS,Sass 更简洁)
  • 丰富的内置函数和模块系统
  • Bootstrap、Foundation 等主流框架采用

缺点:

  • 早期 Ruby 版本编译慢(现已改用 Dart)
  • 学习曲线相对较陡

Less

优点:

  • 语法简单,学习成本低
  • 原生 JavaScript 实现,浏览器端可直接运行
  • 与 CSS 语法高度兼容

缺点:

  • 功能相对较少
  • 没有真正的条件语句和循环
  • 社区活跃度下降

Stylus

优点:

  • 语法最灵活,可省略几乎所有符号
  • 功能强大,接近真正的编程语言
  • 内置强大的函数库

缺点:

  • 灵活的语法可能导致代码风格不统一
  • 社区较小,生态不如 Sass
  • 文档相对较少

选型建议

大型项目 / 团队协作 → Sass (SCSS)
快速上手 / 小型项目 → Less
追求极简 / 个人项目 → Stylus

关键点

  • 变量符号:Sass 用 $,Less 用 @,Stylus 无需符号
  • 语法严格度:Less ≈ Sass (SCSS) > Stylus,Stylus 可省略花括号、冒号、分号
  • 功能完整性:Sass > Stylus > Less,Sass 有完整的模块系统和控制流
  • 生态与社区:Sass > Less > Stylus,主流框架多用 Sass
  • 现状趋势:CSS 原生变量和嵌套逐渐普及,预处理器的必要性在降低