CSS预处理器对比:Sass、Less与Stylus如何选择

引言

CSS预处理器已成为现代前端开发的标准工具,它们通过添加编程特性来增强纯CSS的功能,使样式表更加模块化、可维护且高效。在众多预处理器中,Sass、Less和Stylus是三个最流行的选择,它们各自拥有独特的语法和功能特点。本文将深入比较这三种预处理器,通过详细的代码示例和实际应用场景,帮助你根据项目需求选择最适合的工具。

1. 概述比较

在深入代码细节前,先看一下三种预处理器的基本情况:

特性 Sass Less Stylus
诞生时间 2006年 2009年 2010年
语法风格 两种语法:.scss和.sass 类CSS语法 灵活语法,可省略大部分符号
开发语言 最初Ruby,现在Dart/JS JavaScript JavaScript
学习曲线 中等 较低 较高
社区生态 非常庞大 庞大 相对较小
框架集成 广泛支持 广泛支持 有限支持

2. 语法与基本特性对比

2.1 变量定义

Sass
scss 复制代码
// Sass变量使用$符号
$primary-color: #333;
$secondary-color: #777;
$font-stack: Helvetica, sans-serif;

body {
  color: $primary-color;
  font-family: $font-stack;
}

// Sass的变量支持作用域
.container {
  $local-width: 100%;
  width: $local-width;
}
Less
less 复制代码
// Less变量使用@符号
@primary-color: #333;
@secondary-color: #777;
@font-stack: Helvetica, sans-serif;

body {
  color: @primary-color;
  font-family: @font-stack;
}

// Less的变量也支持作用域
.container {
  @local-width: 100%;
  width: @local-width;
}
Stylus
stylus 复制代码
// Stylus变量不需要特殊符号,但也可以使用$
primary-color = #333
secondary-color = #777
font-stack = Helvetica, sans-serif

body
  color primary-color
  font-family font-stack

// Stylus的变量也支持作用域
.container
  local-width = 100%
  width local-width

2.2 嵌套规则

Sass
scss 复制代码
// Sass嵌套规则
nav {
  background-color: #fff;
  
  ul {
    margin: 0;
    padding: 0;
    list-style: none;
    
    li {
      display: inline-block;
      
      a {
        display: block;
        padding: 6px 12px;
        text-decoration: none;
        
        &:hover {
          background-color: #eee;
        }
      }
    }
  }
}
Less
less 复制代码
// Less嵌套规则
nav {
  background-color: #fff;
  
  ul {
    margin: 0;
    padding: 0;
    list-style: none;
    
    li {
      display: inline-block;
      
      a {
        display: block;
        padding: 6px 12px;
        text-decoration: none;
        
        &:hover {
          background-color: #eee;
        }
      }
    }
  }
}
Stylus
stylus 复制代码
// Stylus嵌套规则
nav
  background-color #fff
  
  ul
    margin 0
    padding 0
    list-style none
    
    li
      display inline-block
      
      a
        display block
        padding 6px 12px
        text-decoration none
        
        &:hover
          background-color #eee

2.3 混合(Mixins)

Sass
scss 复制代码
// Sass混合定义
@mixin border-radius($radius) {
  -webkit-border-radius: $radius;
  -moz-border-radius: $radius;
  -ms-border-radius: $radius;
  border-radius: $radius;
}

// 使用混合
.box {
  @include border-radius(10px);
}

// 带参数默认值的混合
@mixin box-shadow($x: 0, $y: 0, $blur: 1px, $color: #000) {
  -webkit-box-shadow: $x $y $blur $color;
  -moz-box-shadow: $x $y $blur $color;
  box-shadow: $x $y $blur $color;
}

.panel {
  @include box-shadow(2px, 2px, 5px, rgba(0, 0, 0, 0.5));
}

// 可变参数混合
@mixin transition($transitions...) {
  -webkit-transition: $transitions;
  -moz-transition: $transitions;
  transition: $transitions;
}

.fade {
  @include transition(color 0.3s ease-in, background-color 0.5s ease-out);
}
Less
less 复制代码
// Less混合定义
.border-radius(@radius) {
  -webkit-border-radius: @radius;
  -moz-border-radius: @radius;
  -ms-border-radius: @radius;
  border-radius: @radius;
}

// 使用混合
.box {
  .border-radius(10px);
}

// 带参数默认值的混合
.box-shadow(@x: 0, @y: 0, @blur: 1px, @color: #000) {
  -webkit-box-shadow: @x @y @blur @color;
  -moz-box-shadow: @x @y @blur @color;
  box-shadow: @x @y @blur @color;
}

.panel {
  .box-shadow(2px, 2px, 5px, rgba(0, 0, 0, 0.5));
}

// 可变参数混合
.transition(@transitions...) {
  -webkit-transition: @transitions;
  -moz-transition: @transitions;
  transition: @transitions;
}

.fade {
  .transition(color 0.3s ease-in, background-color 0.5s ease-out);
}
Stylus
stylus 复制代码
// Stylus混合定义
border-radius(radius)
  -webkit-border-radius radius
  -moz-border-radius radius
  -ms-border-radius radius
  border-radius radius

// 使用混合
.box
  border-radius(10px)

// 带参数默认值的混合
box-shadow(x = 0, y = 0, blur = 1px, color = #000)
  -webkit-box-shadow x y blur color
  -moz-box-shadow x y blur color
  box-shadow x y blur color

.panel
  box-shadow(2px, 2px, 5px, rgba(0, 0, 0, 0.5))

// 可变参数混合
transition(args...)
  -webkit-transition args
  -moz-transition args
  transition args

.fade
  transition(color 0.3s ease-in, background-color 0.5s ease-out)

3. 高级特性对比

3.1 继承(Extend)

Sass
scss 复制代码
// Sass继承
.message {
  border: 1px solid #ccc;
  padding: 10px;
  color: #333;
}

.success {
  @extend .message;
  border-color: green;
}

.error {
  @extend .message;
  border-color: red;
}

// 占位选择器(Placeholder Selectors)
%btn-base {
  display: inline-block;
  padding: 6px 12px;
  text-align: center;
  border-radius: 4px;
}

.btn-primary {
  @extend %btn-base;
  background-color: #007bff;
  color: white;
}

.btn-secondary {
  @extend %btn-base;
  background-color: #6c757d;
  color: white;
}
Less
less 复制代码
// Less继承
.message {
  border: 1px solid #ccc;
  padding: 10px;
  color: #333;
}

.success {
  &:extend(.message);
  border-color: green;
}

.error {
  &:extend(.message);
  border-color: red;
}

// Less中没有占位选择器的概念,但可以使用混合实现类似功能
.btn-base() {
  display: inline-block;
  padding: 6px 12px;
  text-align: center;
  border-radius: 4px;
}

.btn-primary {
  .btn-base();
  background-color: #007bff;
  color: white;
}

.btn-secondary {
  .btn-base();
  background-color: #6c757d;
  color: white;
}
Stylus
stylus 复制代码
// Stylus继承
.message
  border 1px solid #ccc
  padding 10px
  color #333

.success
  @extend .message
  border-color green

.error
  @extend .message
  border-color red

// Stylus也支持占位符选择器
$btn-base
  display inline-block
  padding 6px 12px
  text-align center
  border-radius 4px

.btn-primary
  @extend $btn-base
  background-color #007bff
  color white

.btn-secondary
  @extend $btn-base
  background-color #6c757d
  color white

3.2 函数和运算

Sass
scss 复制代码
// Sass函数和运算
$base-size: 16px;

// 自定义函数
@function calculate-width($col-count, $total-cols: 12) {
  @return percentage($col-count / $total-cols);
}

.container {
  // 数学运算
  padding: $base-size / 2;
  // 函数调用
  width: calculate-width(8);
}

// 颜色函数
.button {
  background-color: #3498db;
  
  &:hover {
    // 颜色变暗
    background-color: darken(#3498db, 15%);
  }
  
  &.light {
    // 颜色变亮
    background-color: lighten(#3498db, 15%);
  }
  
  &.transparent {
    // 透明度调整
    background-color: rgba(#3498db, 0.5);
  }
}

// 字符串函数
$font-path: 'assets/fonts/';
$font-name: 'opensans';
$font-file: $font-path + $font-name + '.woff';

@font-face {
  font-family: 'Open Sans';
  src: url(#{$font-file});
}
Less
less 复制代码
// Less函数和运算
@base-size: 16px;

// 自定义函数(通过混合实现)
.calculate-width(@col-count, @total-cols: 12) {
  @result: percentage(@col-count / @total-cols);
  // Less混合返回值
  & { width: @result; }
}

.container {
  // 数学运算
  padding: @base-size / 2;
  // 函数调用
  .calculate-width(8);
}

// 颜色函数
.button {
  background-color: #3498db;
  
  &:hover {
    // 颜色变暗
    background-color: darken(#3498db, 15%);
  }
  
  &.light {
    // 颜色变亮
    background-color: lighten(#3498db, 15%);
  }
  
  &.transparent {
    // 透明度调整
    background-color: fade(#3498db, 50%);
  }
}

// 字符串函数
@font-path: 'assets/fonts/';
@font-name: 'opensans';
@font-file: @font-path + @font-name + '.woff';

@font-face {
  font-family: 'Open Sans';
  src: url(@{font-file});
}
Stylus
stylus 复制代码
// Stylus函数和运算
base-size = 16px

// 自定义函数
calculate-width(col-count, total-cols = 12)
  return percentage(col-count / total-cols)

.container
  // 数学运算
  padding base-size / 2
  // 函数调用
  width calculate-width(8)

// 颜色函数
.button
  background-color #3498db
  
  &:hover
    // 颜色变暗
    background-color darken(#3498db, 15%)
  
  &.light
    // 颜色变亮
    background-color lighten(#3498db, 15%)
  
  &.transparent
    // 透明度调整
    background-color rgba(#3498db, 0.5)

// 字符串函数
font-path = 'assets/fonts/'
font-name = 'opensans'
font-file = font-path + font-name + '.woff'

@font-face
  font-family 'Open Sans'
  src url(font-file)

3.3 条件语句和循环

Sass
scss 复制代码
// Sass条件语句
$theme: 'dark';

.container {
  @if $theme == 'light' {
    background-color: #fff;
    color: #333;
  } @else if $theme == 'dark' {
    background-color: #333;
    color: #fff;
  } @else {
    background-color: #f5f5f5;
    color: #555;
  }
}

// Sass循环
// for循环
@for $i from 1 through 5 {
  .col-#{$i} {
    width: 20% * $i;
  }
}

// each循环(遍历列表)
$social-colors: (
  facebook: #3b5998,
  twitter: #1da1f2,
  instagram: #e1306c
);

@each $platform, $color in $social-colors {
  .btn-#{$platform} {
    background-color: $color;
    color: white;
  }
}

// while循环
$i: 1;
$max: 5;

@while $i <= $max {
  .mt-#{$i} {
    margin-top: $i * 0.25rem;
  }
  $i: $i + 1;
}
Less
less 复制代码
// Less条件语句(通过混合实现)
@theme: 'dark';

.theme-styles() when (@theme = 'light') {
  background-color: #fff;
  color: #333;
}

.theme-styles() when (@theme = 'dark') {
  background-color: #333;
  color: #fff;
}

.theme-styles() when (default()) {
  background-color: #f5f5f5;
  color: #555;
}

.container {
  .theme-styles();
}

// Less循环
// for循环 (使用循环混合)
.generate-columns(@i: 1) when (@i <= 5) {
  .col-@{i} {
    width: 20% * @i;
  }
  .generate-columns(@i + 1);
}
.generate-columns();

// each循环
@social-colors: {
  facebook: #3b5998;
  twitter: #1da1f2;
  instagram: #e1306c;
}

.generate-social-btns(@i: 1) when (@i <= length(@social-colors)) {
  @platform: extract(keys(@social-colors), @i);
  @color: extract(values(@social-colors), @i);
  
  .btn-@{platform} {
    background-color: @color;
    color: white;
  }
  
  .generate-social-btns(@i + 1);
}
.generate-social-btns();

// while循环 (使用递归混合)
.generate-margins(@i: 1) when (@i <= 5) {
  .mt-@{i} {
    margin-top: @i * 0.25rem;
  }
  .generate-margins(@i + 1);
}
.generate-margins();
Stylus
stylus 复制代码
// Stylus条件语句
theme = 'dark'

.container
  if theme == 'light'
    background-color #fff
    color #333
  else if theme == 'dark'
    background-color #333
    color #fff
  else
    background-color #f5f5f5
    color #555

// Stylus循环
// for循环
for i in (1..5)
  .col-{i}
    width 20% * i

// each循环
social-colors = {
  facebook: #3b5998,
  twitter: #1da1f2,
  instagram: #e1306c
}

for platform, color in social-colors
  .btn-{platform}
    background-color color
    color white

// while循环
i = 1
max = 5

while i <= max
  .mt-{i}
    margin-top i * 0.25rem
  i = i + 1

4. 实际应用场景

4.1 响应式网格系统

Sass
scss 复制代码
// Sass实现响应式网格系统
$grid-columns: 12;
$grid-gutter: 30px;
$breakpoints: (
  xs: 0,
  sm: 576px,
  md: 768px,
  lg: 992px,
  xl: 1200px
);

.container {
  width: 100%;
  padding-right: $grid-gutter / 2;
  padding-left: $grid-gutter / 2;
  margin-right: auto;
  margin-left: auto;
  
  @each $breakpoint, $width in $breakpoints {
    @if $width > 0 {
      @media (min-width: $width) {
        max-width: $width;
      }
    }
  }
}

.row {
  display: flex;
  flex-wrap: wrap;
  margin-right: -$grid-gutter / 2;
  margin-left: -$grid-gutter / 2;
}

@each $breakpoint, $width in $breakpoints {
  $infix: if($breakpoint == 'xs', '', '-#{$breakpoint}');
  
  @media (min-width: $width) {
    @for $i from 1 through $grid-columns {
      .col#{$infix}-#{$i} {
        flex: 0 0 percentage($i / $grid-columns);
        max-width: percentage($i / $grid-columns);
        padding-right: $grid-gutter / 2;
        padding-left: $grid-gutter / 2;
      }
    }
  }
}
Less
less 复制代码
// Less实现响应式网格系统
@grid-columns: 12;
@grid-gutter: 30px;
@breakpoint-xs: 0;
@breakpoint-sm: 576px;
@breakpoint-md: 768px;
@breakpoint-lg: 992px;
@breakpoint-xl: 1200px;

.container {
  width: 100%;
  padding-right: @grid-gutter / 2;
  padding-left: @grid-gutter / 2;
  margin-right: auto;
  margin-left: auto;
  
  @media (min-width: @breakpoint-sm) {
    max-width: @breakpoint-sm;
  }
  
  @media (min-width: @breakpoint-md) {
    max-width: @breakpoint-md;
  }
  
  @media (min-width: @breakpoint-lg) {
    max-width: @breakpoint-lg;
  }
  
  @media (min-width: @breakpoint-xl) {
    max-width: @breakpoint-xl;
  }
}

.row {
  display: flex;
  flex-wrap: wrap;
  margin-right: -@grid-gutter / 2;
  margin-left: -@grid-gutter / 2;
}

.make-grid-columns(@prefix, @grid-columns) {
  .col-loop(@i) when (@i <= @grid-columns) {
    .col@{prefix}-@{i} {
      flex: 0 0 percentage(@i / @grid-columns);
      max-width: percentage(@i / @grid-columns);
      padding-right: @grid-gutter / 2;
      padding-left: @grid-gutter / 2;
    }
    .col-loop(@i + 1);
  }
  .col-loop(1);
}

// XS breakpoint
.make-grid-columns('', @grid-columns);

// SM breakpoint
@media (min-width: @breakpoint-sm) {
  .make-grid-columns('-sm', @grid-columns);
}

// MD breakpoint
@media (min-width: @breakpoint-md) {
  .make-grid-columns('-md', @grid-columns);
}

// LG breakpoint
@media (min-width: @breakpoint-lg) {
  .make-grid-columns('-lg', @grid-columns);
}

// XL breakpoint
@media (min-width: @breakpoint-xl) {
  .make-grid-columns('-xl', @grid-columns);
}
Stylus
stylus 复制代码
// Stylus实现响应式网格系统
grid-columns = 12
grid-gutter = 30px
breakpoints = {
  xs: 0,
  sm: 576px,
  md: 768px,
  lg: 992px,
  xl: 1200px
}

.container
  width 100%
  padding-right grid-gutter / 2
  padding-left grid-gutter / 2
  margin-right auto
  margin-left auto
  
  for breakpoint, width in breakpoints
    if width > 0
      @media (min-width: width)
        max-width width

.row
  display flex
  flex-wrap wrap
  margin-right -(grid-gutter / 2)
  margin-left -(grid-gutter / 2)

for breakpoint, width in breakpoints
  infix = breakpoint == 'xs' ? '' : '-' + breakpoint
  
  @media (min-width: width)
    for i in (1..grid-columns)
      .col{infix}-{i}
        flex 0 0 percentage(i / grid-columns)
        max-width percentage(i / grid-columns)
        padding-right grid-gutter / 2
        padding-left grid-gutter / 2

4.2 主题系统

Sass
scss 复制代码
// Sass主题系统
// _variables.scss
$themes: (
  light: (
    bg-color: #ffffff,
    text-color: #333333,
    primary-color: #4285f4,
    secondary-color: #fbbc05,
    border-color: #e0e0e0
  ),
  dark: (
    bg-color: #121212,
    text-color: #f5f5f5,
    primary-color: #8ab4f8,
    secondary-color: #ffd04b,
    border-color: #333333
  )
);

// _mixins.scss
@mixin themed() {
  @each $theme, $map in $themes {
    .theme-#{$theme} & {
      $theme-map: () !global;
      @each $key, $value in $map {
        $theme-map: map-merge($theme-map, ($key: $value)) !global;
      }
      @content;
      $theme-map: null !global;
    }
  }
}

@function t($key) {
  @return map-get($theme-map, $key);
}

// main.scss
@import 'variables';
@import 'mixins';

body {
  margin: 0;
  font-family: Arial, sans-serif;
  transition: all 0.3s ease;
}

.card {
  @include themed() {
    background-color: t('bg-color');
    color: t('text-color');
    border: 1px solid t('border-color');
  }
  border-radius: 8px;
  padding: 20px;
  margin: 10px;
  box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
}

.button {
  @include themed() {
    background-color: t('primary-color');
    color: t('bg-color');
    border: 1px solid t('primary-color');
    
    &:hover {
      background-color: darken(t('primary-color'), 10%);
    }
  }
  padding: 10px 15px;
  border-radius: 4px;
  cursor: pointer;
  transition: all 0.2s ease;
}

// 使用主题
.theme-light {
  // light theme is active
}

.theme-dark {
  // dark theme is active
}
Less
less 复制代码
// Less主题系统
// variables.less
@themes: {
  light: {
    bg-color: #ffffff;
    text-color: #333333;
    primary-color: #4285f4;
    secondary-color: #fbbc05;
    border-color: #e0e0e0;
  };
  dark: {
    bg-color: #121212;
    text-color: #f5f5f5;
    primary-color: #8ab4f8;
    secondary-color: #ffd04b;
    border-color: #333333;
  };
};

// mixins.less
.themed-styles(@rules) {
  each(@themes, {
    .theme-@{key} & {
      @theme-props: @value;
      @rules();
    }
  });
}

.t(@property) {
  @result: @theme-props[@@property];
}

// main.less
@import 'variables.less';
@import 'mixins.less';

body {
  margin: 0;
  font-family: Arial, sans-serif;
  transition: all 0.3s ease;
}

.card {
  .themed-styles({
    background-color: .t(bg-color);
    color: .t(text-color);
    border: 1px solid .t(border-color);
  });
  border-radius: 8px;
  padding: 20px;
  margin: 10px;
  box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
}

.button {
  .themed-styles({
    background-color: .t(primary-color);
    color: .t(bg-color);
    border: 1px solid .t(primary-color);
    
    &:hover {
      background-color: darken(.t(primary-color), 10%);
    }
  });
  padding: 10px 15px;
  border-radius: 4px;
  cursor: pointer;
  transition: all 0.2s ease;
}

// 使用主题
.theme-light {
  // light theme is active
}

.theme-dark {
  // dark theme is active
}
Stylus
stylus 复制代码
// Stylus主题系统
// variables.styl
themes = {
  light: {
    bg-color: #ffffff,
    text-color: #333333,
    primary-color: #4285f4,
    secondary-color: #fbbc05,
    border-color: #e0e0e0
  },
  dark: {
    bg-color: #121212,
    text-color: #f5f5f5,
    primary-color: #8ab4f8,
    secondary-color: #ffd04b,
    border-color: #333333
  }
}

// mixins.styl
themed()
  for theme, props in themes
    .theme-{theme} &
      theme-map = props
      {block}

t(key)
  return theme-map[key]

// main.styl
@import 'variables'
@import 'mixins'

body
  margin 0
  font-family Arial, sans-serif
  transition all 0.3s ease

.card
  +themed()
    background-color t('bg-color')
    color t('text-color')
    border 1px solid t('border-color')
  border-radius 8px
  padding 20px
  margin 10px
  box-shadow 0 2px 5px rgba(0, 0, 0, 0.1)

.button
  +themed()
    background-color t('primary-color')
    color t('bg-color')
    border 1px solid t('primary-color')
    
    &:hover
      background-color darken(t('primary-color'), 10%)
  padding 10px 15px
  border-radius 4px
  cursor pointer
  transition all 0.2s ease

// 使用主题
.theme-light
  // light theme is active

.theme-dark
  // dark theme is active

5. 各预处理器的优缺点分析

5.1 Sass

优点:

  1. 功能最为强大完整,拥有最丰富的功能集
  2. 有两种语法选择:缩进式的.sass和兼容CSS的.scss
  3. 社区最大,资源最丰富,有大量现成的库和框架(如Bootstrap、Foundation等)
  4. 最成熟的变量、函数和模块系统
  5. 出色的错误报告和调试工具
  6. 可扩展性强,支持自定义函数和插件

缺点:

  1. 相比Less,安装和配置稍微复杂一些
  2. 完整学习所有功能需要较长时间
  3. 编译速度相对较慢,尤其是大型项目

5.2 Less

优点:

  1. 语法最接近CSS,学习曲线低
  2. 基于JavaScript,可以在浏览器端运行
  3. 安装配置简单,易于集成
  4. 与JavaScript结合紧密,便于Web开发者上手
  5. 编译速度快,适合中小型项目

缺点:

  1. 功能不如Sass丰富,特别是在高级编程功能方面
  2. 没有真正的函数功能,只能通过混合模拟
  3. 运行时错误处理不如Sass完善
  4. 扩展性相对较弱

5.3 Stylus

优点:

  1. 语法最为灵活,几乎所有标点和括号都是可选的
  2. 具有强大的编程能力,接近JavaScript的表达能力
  3. 内置函数库丰富
  4. 极简主义风格,代码最为简洁
  5. 性能优秀,编译速度快

缺点:

  1. 社区和生态系统相对较小
  2. 灵活的语法可能导致代码风格不统一
  3. 学习曲线较陡峭,特别是对于CSS新手
  4. 文档和资源不如Sass和Less丰富
  5. 主流框架和库的支持较少

6. 实际项目选择建议

根据上述对比和分析,以下是针对不同场景的CSS预处理器选择建议:

6.1 何时选择Sass

适合以下场景:

  • 大型复杂项目,需要完整的功能集
  • 团队已有Sass经验,或者项目与使用Sass的库有集成需求
  • 需要使用高级功能,如模块系统、占位选择器等
  • 使用Ruby on Rails、Angular等已集成Sass的框架
  • 长期维护的企业级应用,需要良好的扩展性和模块化

推荐使用Sass的情况:

scss 复制代码
// 如果你需要使用以下功能,推荐Sass
// 1. 模块化系统
@use 'buttons';
@use 'forms';

// 2. 占位选择器
%shared-style {
  border: 1px solid #ccc;
  padding: 10px;
}

.button {
  @extend %shared-style;
  // 更多样式...
}

// 3. 强大的内置函数
$colors: (
  primary: #3498db,
  secondary: #2ecc71
);

@function color($name) {
  @return map-get($colors, $name);
}

.element {
  color: color(primary);
}

6.2 何时选择Less

适合以下场景:

  • 中小型项目,需要快速上手
  • 团队主要由Web前端开发者组成,熟悉JavaScript
  • 项目与使用Less的库集成(如早期的Bootstrap)
  • 希望配置简单,构建速度快
  • 项目需要在浏览器中直接编译CSS

推荐使用Less的情况:

less 复制代码
// 如果你需要以下功能,推荐Less
// 1. 浏览器端编译
<link rel="stylesheet/less" type="text/css" href="styles.less" />
<script src="//cdnjs.cloudflare.com/ajax/libs/less.js/3.9.0/less.min.js"></script>

// 2. 简单的变量和混合
@main-color: #3498db;

.button-style {
  background-color: @main-color;
  border-radius: 4px;
}

.primary-button {
  .button-style();
  color: white;
}

// 3. 与JavaScript结合紧密
@link-color: #428bca;
@link-color-hover: darken(@link-color, 15%);

6.3 何时选择Stylus

适合以下场景:

  • 追求极简语法和代码简洁
  • 有Node.js开发背景的团队
  • 需要高性能编译
  • 小型或实验性项目
  • 喜欢灵活的编程风格

推荐使用Stylus的情况:

stylus 复制代码
// 如果你喜欢以下特性,推荐Stylus
// 1. 极简语法
body
  font 14px/1.5 Arial, sans-serif
  background-color #f5f5f5

// 2. 强大的内置函数和表达式
sum(a, b)
  a + b

border-radius()
  -webkit-border-radius arguments
  -moz-border-radius arguments
  border-radius arguments

box
  width sum(10px, 20px)
  border-radius 5px
  
// 3. 隐式混合调用
@import 'mixins'

.element
  button-style() // 无需使用特殊符号调用混合

7. 总结

每种CSS预处理器都有其独特的优势和使用场景:

Sass 是功能最完整、社区最庞大的选择,适合大型项目和长期维护的应用。它提供了强大的模块系统、函数和混合功能,同时支持两种语法格式。虽然学习曲线较陡,但其强大的功能和生态系统使其成为当前最流行的CSS预处理器。

Less 以其接近原生CSS的语法和简单的学习曲线脱颖而出,非常适合中小型项目或需要快速上手的团队。它基于JavaScript,可以在浏览器端运行,配置简单,构建速度快。

Stylus 提供了最灵活的语法和强大的编程能力,适合追求代码简洁性和表达力的开发者。它的语法几乎完全自由,提供了丰富的内置函数,但社区相对较小,资源相对较少。

最终的选择应该基于以下因素:

  • 项目规模和复杂度
  • 团队经验和技术栈
  • 与现有框架或库的兼容性
  • 性能需求
  • 开发效率和维护性考虑

无论选择哪种预处理器,它们都能显著提高CSS的可维护性、可重用性和编写效率,是现代前端开发不可或缺的工具。

相关推荐
努力成为AK大王4 小时前
CSS 入门完整笔记
前端·css
神明不懂浪漫16 小时前
【第四章】CSS(二)——文本外观属性与复合选择器
前端·css·经验分享·笔记
H Journey1 天前
web开发学习:html、css、js
前端·css·html·js
用户059540174461 天前
AI Agent 记忆存储踩坑实录:这个问题让我排查了 3 天,最终用 pytest + Docker 实现秒级回归
前端·css
今日无bug1 天前
Emmet 语法速成指南
前端·css·html
Hello.Reader1 天前
Tailwind CSS v4.3 从入门到实战Vite 安装、响应式布局、暗黑模式与主题配置
前端·css
cxxcode2 天前
CSS Loader 与样式处理链路
前端·css
CappuccinoRose2 天前
CSS、Less、Sass(含 SCSS)、Stylus
前端·css·less·sass·stylus
用户059540174463 天前
把前端内存泄漏排查从2小时压到5分钟,我们把它集成进了CI
前端·css
zhanghaofaowhrql5 天前
为CSDN博客编辑器安装自定义CSS主题,打造个性化写作界面
前端·css·编辑器