轩辕李的博客 轩辕李的博客
首页
  • Java
  • Spring
  • 其他语言
  • 工具
  • JavaScript
  • TypeScript
  • Node.js
  • Vue.js
  • 前端工程化
  • 浏览器与Web API
  • 分布式
  • 代码质量管理
  • 基础
  • 操作系统
  • 计算机网络
  • 编程范式
  • 安全
  • 中间件
  • 心得
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

轩辕李

勇猛精进,星辰大海
首页
  • Java
  • Spring
  • 其他语言
  • 工具
  • JavaScript
  • TypeScript
  • Node.js
  • Vue.js
  • 前端工程化
  • 浏览器与Web API
  • 分布式
  • 代码质量管理
  • 基础
  • 操作系统
  • 计算机网络
  • 编程范式
  • 安全
  • 中间件
  • 心得
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • JavaScript

  • TypeScript

  • Node.js

  • Vue.js

  • 工程化

  • 浏览器与Web API

    • HTML基础-语义化标签与文档结构
    • HTML基础-文本与排版标签
    • HTML基础-列表与表格
    • HTML表单-Input类型详解
    • HTML表单-表单元素与验证
    • HTML交互-多媒体元素
    • HTML工程化-模板与组件化
    • HTML工程化-性能优化
    • CSS基础-选择器与优先级
    • CSS基础-盒模型与布局基础
    • CSS基础-单位与颜色系统
    • CSS基础-文本与字体
    • CSS基础-背景、列表与表格样式
    • CSS布局-Flexbox完全指南
    • CSS布局-Grid网格布局
    • CSS布局-响应式设计实践
    • CSS进阶-动画与过渡
    • CSS进阶-渐变与阴影效果
    • CSS进阶-Transform与3D变换
    • CSS进阶-滤镜与混合模式
    • 现代CSS-CSS预处理器对比
      • 一、CSS预处理器概述
        • 1.1 什么是CSS预处理器
        • 1.2 为什么需要预处理器
        • 1.3 三大预处理器简介
      • 二、Sass详解
        • 2.1 Sass简介
        • 2.2 Sass核心特性
        • 变量
        • 嵌套
        • 混合(Mixins)
        • 继承
        • 函数
        • 控制指令
        • 模块化
      • 三、Less详解
        • 3.1 Less简介
        • 3.2 Less核心特性
        • 变量
        • 嵌套
        • 混合(Mixins)
        • 继承
        • 运算
        • 函数
        • 命名空间
        • 导入
      • 四、Stylus详解
        • 4.1 Stylus简介
        • 4.2 Stylus核心特性
        • 变量
        • 嵌套
        • 混合
        • 函数
        • 控制流
        • 插值
        • 透明混合
      • 五、三者对比
        • 5.1 语法对比
        • 5.2 功能对比
        • 5.3 性能对比
        • 5.4 生态系统对比
      • 六、选择建议
        • 6.1 选择Sass的理由
        • 6.2 选择Less的理由
        • 6.3 选择Stylus的理由
        • 6.4 综合建议
      • 七、总结
    • 现代CSS-CSS-in-JS方案
    • 现代CSS-原子化CSS与Tailwind
    • CSS工程化-架构与规范
    • CSS工程化-性能优化
    • CSS工程化-PostCSS实战指南
    • Web API基础-DOM操作完全指南
    • Web API基础-事件处理与委托
    • Web API基础-BOM与浏览器环境
    • Web API存储-客户端存储方案
    • Web API网络-HTTP请求详解
    • Web API网络-实时通信方案
    • Web API交互-用户体验增强
    • HTML&CSS历代版本新特性
  • 前端
  • 浏览器与Web API
轩辕李
2019-09-02
目录

现代CSS-CSS预处理器对比

CSS预处理器是现代Web开发中不可或缺的工具,它们扩展了CSS的功能,引入了变量、嵌套、混合、函数等编程特性,使CSS更加强大、易于维护和复用。

本文将深入对比三大主流CSS预处理器:Sass、Less和Stylus,帮助你了解它们的特点、语法差异和使用场景,从而选择最适合项目的预处理器。

# 一、CSS预处理器概述

# 1.1 什么是CSS预处理器

CSS预处理器是一种用特定语法编写样式代码,然后编译成标准CSS的工具。它们提供了原生CSS不具备的功能:

  • 变量(Variables):存储可复用的值
  • 嵌套(Nesting):反映HTML结构的嵌套规则
  • 混合(Mixins):复用样式代码块
  • 函数(Functions):动态计算值
  • 运算(Operations):数学运算和颜色操作
  • 导入(Import):模块化组织代码
  • 继承(Extend):继承其他选择器的样式

# 1.2 为什么需要预处理器

原生CSS的局限性:

  • 没有变量,重复值需要手动维护
  • 没有嵌套,选择器冗长重复
  • 没有代码复用机制
  • 缺少逻辑控制能力

预处理器的优势:

  • 提高代码可维护性
  • 增强代码复用性
  • 支持模块化开发
  • 提供编程能力
  • 提升开发效率

# 1.3 三大预处理器简介

特性 Sass Less Stylus
发布时间 2006年 2009年 2010年
实现语言 Ruby(Dart Sass用Dart) JavaScript JavaScript
文件扩展名 .sass / .scss .less .styl
语法风格 严格/宽松 类CSS 极简
社区规模 最大 中等 较小
学习曲线 中等 较低 中等

# 二、Sass详解

# 2.1 Sass简介

Sass(Syntactically Awesome Stylesheets)是最成熟、功能最强大的CSS预处理器,有两种语法:

  • Sass语法(.sass):使用缩进,不需要分号和花括号
  • SCSS语法(.scss):类似CSS,使用分号和花括号(推荐)

安装:

# 使用Dart Sass(推荐)
npm install -g sass

# 或在项目中安装
npm install --save-dev sass

# 2.2 Sass核心特性

# 变量

// 定义变量
$primary-color: #667eea;
$secondary-color: #764ba2;
$base-font-size: 16px;
$border-radius: 8px;

// 使用变量
.button {
  background: $primary-color;
  font-size: $base-font-size;
  border-radius: $border-radius;
}

// 变量作用域
.container {
  $local-padding: 20px; // 局部变量
  padding: $local-padding;
}

// 默认变量(可被覆盖)
$base-spacing: 10px !default;

# 嵌套

// 选择器嵌套
.nav {
  background: #333;
  
  ul {
    list-style: none;
    margin: 0;
    padding: 0;
  }
  
  li {
    display: inline-block;
    
    a {
      color: white;
      text-decoration: none;
      padding: 10px 15px;
      
      &:hover {
        background: #555;
      }
    }
  }
}

// 属性嵌套
.box {
  border: {
    style: solid;
    width: 1px;
    color: #ccc;
    radius: 4px;
  }
  
  font: {
    family: Arial, sans-serif;
    size: 14px;
    weight: bold;
  }
}

// 父选择器引用 &
.button {
  background: #667eea;
  
  &:hover {
    background: #5568d3;
  }
  
  &.active {
    background: #4356be;
  }
  
  .theme-dark & {
    background: #8891f2;
  }
}

# 混合(Mixins)

// 定义混合
@mixin flex-center {
  display: flex;
  justify-content: center;
  align-items: center;
}

// 使用混合
.container {
  @include flex-center;
}

// 带参数的混合
@mixin button-style($bg-color, $text-color: white) {
  background: $bg-color;
  color: $text-color;
  padding: 10px 20px;
  border-radius: 4px;
  border: none;
  cursor: pointer;
  
  &:hover {
    background: darken($bg-color, 10%);
  }
}

.primary-btn {
  @include button-style(#667eea);
}

.danger-btn {
  @include button-style(#e74c3c, white);
}

// 可变参数
@mixin box-shadow($shadows...) {
  box-shadow: $shadows;
}

.card {
  @include box-shadow(
    0 2px 4px rgba(0,0,0,0.1),
    0 4px 8px rgba(0,0,0,0.1)
  );
}

# 继承

// 定义基础样式
.button-base {
  padding: 10px 20px;
  border-radius: 4px;
  border: none;
  cursor: pointer;
  font-size: 14px;
  transition: all 0.3s;
}

// 继承
.primary-button {
  @extend .button-base;
  background: #667eea;
  color: white;
}

.secondary-button {
  @extend .button-base;
  background: #ecf0f1;
  color: #2c3e50;
}

// 占位符选择器(不会输出到CSS中)
%flex-center {
  display: flex;
  justify-content: center;
  align-items: center;
}

.container {
  @extend %flex-center;
}

.modal {
  @extend %flex-center;
}

# 函数

// 内置函数
.element {
  // 颜色函数
  color: darken(#667eea, 20%);
  background: lighten(#667eea, 20%);
  border-color: saturate(#667eea, 30%);
  
  // 数学函数
  width: percentage(0.5); // 50%
  padding: round(10.6px); // 11px
  margin: ceil(10.1px); // 11px
}

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

.text {
  font-size: calculate-rem(24px); // 1.5rem
}

// 复杂函数示例
@function strip-unit($number) {
  @if type-of($number) == 'number' and not unitless($number) {
    @return $number / ($number * 0 + 1);
  }
  @return $number;
}

# 控制指令

// @if 条件判断
@mixin theme-color($theme) {
  @if $theme == 'light' {
    background: white;
    color: black;
  } @else if $theme == 'dark' {
    background: #2c3e50;
    color: white;
  } @else {
    background: gray;
    color: white;
  }
}

.container {
  @include theme-color('dark');
}

// @for 循环
@for $i from 1 through 4 {
  .col-#{$i} {
    width: percentage($i / 4);
  }
}

// @each 遍历
$colors: (
  primary: #667eea,
  success: #2ecc71,
  danger: #e74c3c,
  warning: #f39c12
);

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

// @while 循环
$i: 1;
@while $i <= 3 {
  .item-#{$i} {
    width: 100px * $i;
  }
  $i: $i + 1;
}

# 模块化

// _variables.scss
$primary-color: #667eea;
$secondary-color: #764ba2;

// _mixins.scss
@mixin flex-center {
  display: flex;
  justify-content: center;
  align-items: center;
}

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

// 或使用新的@use(推荐)
@use 'variables' as vars;
@use 'mixins';

.container {
  background: vars.$primary-color;
  @include mixins.flex-center;
}

# 三、Less详解

# 3.1 Less简介

Less(Leaner Style Sheets)是一个轻量级的CSS预处理器,语法更接近CSS,学习曲线较低。

安装:

# 全局安装
npm install -g less

# 项目中安装
npm install --save-dev less

# 3.2 Less核心特性

# 变量

// 定义变量
@primary-color: #667eea;
@secondary-color: #764ba2;
@base-font-size: 16px;

// 使用变量
.button {
  background: @primary-color;
  font-size: @base-font-size;
}

// 变量插值
@image-path: '../images';

.header {
  background-image: url('@{image-path}/logo.png');
}

// 延迟加载(变量可以在定义前使用)
.container {
  color: @text-color;
}

@text-color: #333;

# 嵌套

// 选择器嵌套(与Sass类似)
.nav {
  background: #333;
  
  ul {
    list-style: none;
    
    li {
      display: inline-block;
      
      a {
        color: white;
        
        &:hover {
          color: #667eea;
        }
      }
    }
  }
}

// @ 规则嵌套
.component {
  width: 300px;
  
  @media (min-width: 768px) {
    width: 600px;
  }
  
  @supports (display: grid) {
    display: grid;
  }
}

# 混合(Mixins)

// 定义混合
.flex-center {
  display: flex;
  justify-content: center;
  align-items: center;
}

// 使用混合(带括号则不会输出到CSS)
.flex-center() {
  display: flex;
  justify-content: center;
  align-items: center;
}

.container {
  .flex-center();
}

// 带参数的混合
.button-style(@bg-color, @text-color: white) {
  background: @bg-color;
  color: @text-color;
  padding: 10px 20px;
  border-radius: 4px;
  
  &:hover {
    background: darken(@bg-color, 10%);
  }
}

.primary-btn {
  .button-style(#667eea);
}

// 带条件的混合
.mixin-if(@condition) when (@condition = true) {
  color: red;
}

.mixin-if(@condition) when (@condition = false) {
  color: blue;
}

.element {
  .mixin-if(true);
}

# 继承

// Less使用:extend伪类
.button-base {
  padding: 10px 20px;
  border-radius: 4px;
  border: none;
}

.primary-button {
  &:extend(.button-base);
  background: #667eea;
  color: white;
}

// 扩展所有实例
.button-base {
  padding: 10px 20px;
  
  &:hover {
    opacity: 0.8;
  }
}

.primary-button {
  &:extend(.button-base all);
  background: #667eea;
}

# 运算

// 数学运算
.container {
  width: 100% - 20px;
  padding: 10px * 2;
  margin: (10px + 5px) / 2;
}

// 颜色运算
@base-color: #667eea;

.element {
  color: @base-color + #111;
  background: @base-color * 0.8;
}

// 单位转换
.box {
  width: 100px + 2em; // Less会尝试转换
}

# 函数

// 颜色函数
.element {
  color: darken(#667eea, 20%);
  background: lighten(#667eea, 20%);
  border: 1px solid fade(#667eea, 50%);
}

// 数学函数
.box {
  width: percentage(0.5); // 50%
  height: round(10.6px); // 11px
  padding: ceil(10.1px); // 11px
}

// 字符串函数
.element {
  content: replace("Hello World", "World", "Less");
}

// 列表函数
@list: 1px, 2px, 3px;
.element {
  padding: extract(@list, 1); // 1px
}

# 命名空间

// 定义命名空间
#theme {
  .light {
    background: white;
    color: black;
  }
  
  .dark {
    background: #2c3e50;
    color: white;
  }
}

// 使用命名空间
.container {
  #theme.dark();
}

# 导入

// 导入Less文件
@import 'variables';
@import 'mixins';

// 导入CSS文件
@import (css) 'reset.css';

// 导入选项
@import (reference) 'bootstrap'; // 只引用不输出
@import (inline) 'custom.css'; // 直接插入内容
@import (less) 'style.css'; // 当作Less文件处理
@import (once) 'file.less'; // 只导入一次(默认)
@import (multiple) 'file.less'; // 允许多次导入

# 四、Stylus详解

# 4.1 Stylus简介

Stylus是最灵活的CSS预处理器,语法极简,可选的分号、冒号和花括号使代码更简洁。

安装:

# 全局安装
npm install -g stylus

# 项目中安装
npm install --save-dev stylus

# 4.2 Stylus核心特性

# 变量

// 定义变量(无需特殊符号)
primary-color = #667eea
secondary-color = #764ba2
base-font-size = 16px

// 使用变量
.button
  background primary-color
  font-size base-font-size

// 属性查找
.box
  width 100px
  height @width // 引用width的值
  margin (@width / 2)

# 嵌套

// 选择器嵌套(无需花括号)
.nav
  background #333
  
  ul
    list-style none
    
    li
      display inline-block
      
      a
        color white
        text-decoration none
        
        &:hover
          color primary-color

// 父选择器引用
.button
  background primary-color
  
  &:hover
    background darken(primary-color, 10%)
  
  &.active
    background darken(primary-color, 20%)

# 混合

// 定义混合(函数式)
flex-center()
  display flex
  justify-content center
  align-items center

// 使用混合
.container
  flex-center()

// 带参数的混合
button-style(bg-color, text-color = white)
  background bg-color
  color text-color
  padding 10px 20px
  border-radius 4px
  
  &:hover
    background darken(bg-color, 10%)

.primary-btn
  button-style(#667eea)

// 块混合
with-border()
  border 1px solid #ccc
  {block}

.box
  +with-border()
    padding 10px
    margin 5px

# 函数

// 定义函数
add(a, b)
  a + b

.box
  width add(100px, 50px)

// 颜色函数
.element
  color darken(#667eea, 20%)
  background lighten(#667eea, 20%)
  border-color rgba(#667eea, 0.5)

// 内置函数
.container
  width unit(100, 'px') // 100px
  height percentage(0.5) // 50%

// 条件函数
color-type(color)
  if lightness(color) > 50%
    'light'
  else
    'dark'

.element
  data-theme color-type(#667eea)

# 控制流

// 条件语句
theme-color(theme)
  if theme == 'light'
    background white
    color black
  else if theme == 'dark'
    background #2c3e50
    color white
  else
    background gray
    color white

.container
  theme-color('dark')

// 循环
for i in 1..4
  .col-{i}
    width (100% / 4 * i)

// 遍历
colors = {
  primary: #667eea,
  success: #2ecc71,
  danger: #e74c3c
}

for name, color in colors
  .btn-{name}
    background color

# 插值

// 选择器插值
sides = top right bottom left

for side in sides
  .margin-{side}
    margin-{side} 10px

// 属性插值
vendor(prop, args)
  -webkit-{prop} args
  -moz-{prop} args
  {prop} args

.box
  vendor('border-radius', 5px)

# 透明混合

// 与CSS属性同名的混合会自动应用
border-radius(n)
  -webkit-border-radius n
  -moz-border-radius n
  border-radius n

.box
  border-radius 5px // 自动展开

// 块属性
border-radius(n)
  -webkit-border-radius n
  -moz-border-radius n
  border-radius n

body
  font 14px Arial, sans-serif
  border-radius 5px

# 五、三者对比

# 5.1 语法对比

相同的样式,三种写法:

// Sass/SCSS
$primary-color: #667eea;

@mixin button-style {
  padding: 10px 20px;
  border-radius: 4px;
  background: $primary-color;
  
  &:hover {
    background: darken($primary-color, 10%);
  }
}

.button {
  @include button-style;
}
// Less
@primary-color: #667eea;

.button-style() {
  padding: 10px 20px;
  border-radius: 4px;
  background: @primary-color;
  
  &:hover {
    background: darken(@primary-color, 10%);
  }
}

.button {
  .button-style();
}
// Stylus
primary-color = #667eea

button-style()
  padding 10px 20px
  border-radius 4px
  background primary-color
  
  &:hover
    background darken(primary-color, 10%)

.button
  button-style()

# 5.2 功能对比

功能 Sass Less Stylus
变量 $var @var var
嵌套 ✅ ✅ ✅
混合 @mixin/@include .mixin() mixin()
继承 @extend :extend @extend
导入 @import/@use @import @import
运算 ✅ ✅ ✅
函数 丰富 丰富 丰富
条件 @if/@else when if/else
循环 @for/@each/@while 有限 for
内置函数 非常丰富 丰富 丰富
JavaScript求值 ❌ ✅ ✅

# 5.3 性能对比

编译速度(相对比较):

  1. Dart Sass:最快(使用Dart编写)
  2. Less:快(JavaScript实现)
  3. Stylus:较快(JavaScript实现)
  4. Ruby Sass:慢(已废弃)

生成的CSS质量:

  • 三者生成的CSS质量相似
  • Sass的 @extend 优化最好
  • 都支持压缩和Source Map

# 5.4 生态系统对比

方面 Sass Less Stylus
社区规模 最大 中等 较小
流行框架 Bootstrap 4+, Bulma Bootstrap 3 Vuetify(部分)
工具支持 最完善 完善 一般
插件数量 最多 较多 较少
学习资源 最丰富 丰富 一般
维护状态 活跃 活跃 较慢

# 六、选择建议

# 6.1 选择Sass的理由

✅ 适合场景:

  • 大型项目或企业级应用
  • 需要强大的功能和完整的生态
  • 团队成员熟悉Sass
  • 使用Bootstrap、Bulma等框架

✅ 优势:

  • 功能最强大、最完善
  • 社区最大、资源最丰富
  • 工具链最成熟
  • 文档最详细

❌ 劣势:

  • 学习曲线相对较陡
  • 语法较严格

推荐指数: ⭐⭐⭐⭐⭐

# 6.2 选择Less的理由

✅ 适合场景:

  • 中小型项目
  • 团队更熟悉JavaScript
  • 需要在浏览器端编译
  • 使用Ant Design等基于Less的UI库

✅ 优势:

  • 语法最接近CSS,学习成本低
  • 纯JavaScript实现,易集成
  • 支持浏览器端编译
  • 可以使用JavaScript表达式

❌ 劣势:

  • 功能相对较少
  • 社区规模较小
  • 逻辑控制能力较弱

推荐指数: ⭐⭐⭐⭐

# 6.3 选择Stylus的理由

✅ 适合场景:

  • 追求极简语法
  • 小型项目或个人项目
  • 喜欢灵活的语法风格

✅ 优势:

  • 语法最灵活、最简洁
  • 可选的符号(冒号、分号、花括号)
  • 功能丰富
  • 透明混合特性独特

❌ 劣势:

  • 社区最小
  • 学习资源较少
  • 维护更新较慢
  • 团队协作可能因语法灵活性产生分歧

推荐指数: ⭐⭐⭐

# 6.4 综合建议

项目选择流程:

是否使用了特定UI框架?
├─ 是 → 使用框架推荐的预处理器
│         (Bootstrap 4+用Sass, Ant Design用Less)
└─ 否 → 继续

团队是否已有偏好?
├─ 是 → 使用团队熟悉的
└─ 否 → 继续

项目规模和复杂度?
├─ 大型/复杂 → Sass (功能强大、生态完善)
├─ 中型 → Less (学习成本低、易上手)
└─ 小型/个人 → Stylus (语法简洁) 或 Sass

2024年推荐:

  1. 首选Sass:最成熟、最强大、社区最大
  2. 次选Less:学习成本低、JavaScript生态
  3. 可选Stylus:追求极简或特定需求

# 七、总结

CSS预处理器是现代前端开发的重要工具:

Sass/SCSS:

  • 功能最强大、最完善
  • 社区最大、生态最好
  • 适合大型项目
  • 推荐作为首选

Less:

  • 语法接近CSS,易学习
  • JavaScript生态集成好
  • 适合中小型项目
  • 适合JavaScript团队

Stylus:

  • 语法最灵活简洁
  • 功能丰富
  • 适合小型项目或个人
  • 社区相对较小

选择建议:

  1. 新项目首选Sass(特别是Dart Sass)
  2. 如果使用特定UI库,跟随其选择
  3. 考虑团队技术栈和偏好
  4. 评估项目规模和复杂度

无论选择哪个预处理器,都要:

  • 遵循最佳实践
  • 保持代码组织良好
  • 合理使用功能
  • 注意性能影响
  • 编写可维护的代码

祝你变得更强!

编辑 (opens new window)
#CSS#Sass#Less#Stylus
上次更新: 2025/11/20
CSS进阶-滤镜与混合模式
现代CSS-CSS-in-JS方案

← CSS进阶-滤镜与混合模式 现代CSS-CSS-in-JS方案→

最近更新
01
AI编程时代的一些心得
09-11
02
Claude Code与Codex的协同工作
09-01
03
Claude Code 最佳实践(个人版)
08-01
更多文章>
Theme by Vdoing | Copyright © 2018-2025 京ICP备2021021832号-2 | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式