Sass(SCSS)和Less CSS预处理器详解
Sass (Syntactically Awesome Style Sheets) 和 Less (Leaner Style Sheets) 是目前最流行的两种 CSS 预处理器。它们扩展了 CSS 语言的功能,允许开发者使用变量、混合 (Mixins)、嵌套、函数、继承等编程特性来编写样式,极大地提高了 CSS 的可维护性、代码复用性和开发效率。本篇将详细介绍 Sass 和 Less 的特性、语法以及它们之间的异同。
核心思想:Sass 和 Less 通过添加编程语言特性(如变量、混合、嵌套、函数等),将样式代码模块化、动态化,最终编译为标准 CSS,从而提升 CSS 编写效率和可维护性。
一、CSS 预处理器概述
1.1 为什么需要 CSS 预处理器?
传统的 CSS 有以下痛点:
- 重复性:颜色、字体大小等值可能在多处重复,修改时需要修改所有地方。
- 可维护性差:缺乏变量、函数等概念,难以模块化和抽象。
- 没有逻辑性:无法进行条件判断、循环等操作。
- 选择器冗余:深度嵌套的选择器导致代码量庞大。
- 供应商前缀:手动添加
-webkit-,-moz-等前缀繁琐且易出错。
CSS 预处理器通过引入编程语言的特性来解决这些问题,让 CSS 编写从“苦力活”变成“编程”。
1.2 它们的工作原理
开发者编写 Sass 或 Less 代码(通常是 .scss, .sass 或 .less 文件),然后通过各自的编译器将这些代码转换成浏览器能够理解的标准 CSS 文件。这个编译过程可以在开发时自动完成,也可以在部署前手动执行。
二、Sass / SCSS 详解
2.1 Sass 简介
Sass (Syntactically Awesome Style Sheets) 诞生于 2007 年,是资格最老、功能最强大的 CSS 预处理器之一。它由 Ruby 语言开发。Sass 提供了两种语法:
- Sass (缩进语法):这是早期版本的 Sass 语法,使用缩进代替大括号,用换行代替分号,类似于 Stylus 或 Python。文件扩展名为
.sass。 - SCSS (Sassy CSS):Sass 3.0 引入的语法,完全兼容 CSS 语法。这意味着任何有效的 CSS 代码都是有效的 SCSS 代码。文件扩展名为
.scss。SCSS 是目前 Sass 的主流和推荐语法。
本文主要以 SCSS 语法进行讲解。
2.2 安装
Sass 最初基于 Ruby,现在主流的实现是 Dart Sass (由 Google 开发,推荐)。
1 | # 全局安装 Dart Sass |
2.3 核心特性 (SCSS 语法)
2.3.1 变量 (Variables)
使用 $ 符号定义变量,用于存储颜色、字体、尺寸等值。
1 | // _variables.scss |
编译为:
1 | body { |
2.3.2 嵌套 (Nesting)
允许将相关的 CSS 规则嵌套在父选择器中,避免重复编写父选择器。
1 | nav { |
编译为:
1 | nav ul { |
2.3.3 混合器 (Mixins)
使用 @mixin 定义可重用的样式块,然后用 @include 引入。可以接受参数。
1 | @mixin border-radius($radius) { |
编译为:
1 | .button { |
2.3.4 继承 (@extend)
使用 @extend 允许一个选择器继承另一个选择器的所有样式,同时保持代码 DRY (Don’t Repeat Yourself)。
1 | .message { |
编译为:
1 | .message, .message--success, .message--error { |
注意: @extend 会合并选择器,减少代码重复,但过度使用可能导致生成的 CSS 选择器链太长,增加复杂性。考虑优先使用 Mixins。
2.3.5 函数 (Functions)
Sass 提供了丰富的内建函数(如颜色函数 darken(), lighten(), 数学函数 round(), 字符串函数 to-upper-case() 等),你也可以自定义函数。
1 | @function calculate-column-width($total-width, $columns, $gutter) { |
2.3.6 控制指令 (@if, @for, @each, @while)
Sass 支持条件判断和循环,为 CSS 带来编程逻辑。
1 | // @if / @else if / @else |
2.3.7 模块化 (@import)
使用 @import 导入 .scss 或 .sass 文件。如果导入的文件名以下划线开头(例如 _variables.scss),Sass 会将其视为局部文件,编译时不会单独输出为 CSS 文件。
1 | // _base.scss |
三、Less 详解
3.1 Less 简介
Less (Leaner Style Sheets) 诞生于 2009 年,是受 Sass 启发而创建的,旨在提供一种更“亲近”CSS 的预处理器。它基于 JavaScript 开发,可以直接在浏览器端或 Node.js 环境中编译。Less 的语法与 SCSS 非常相似,因为它也基于 CSS 的语法。
3.2 安装
1 | # 全局安装 Less |
3.3 核心特性
Less 的核心特性与 Sass 大同小异,但语法上存在细微差别。
3.3.1 变量 (Variables)
使用 @ 符号定义变量。
1 | // variables.less |
3.3.2 嵌套 (Nesting)
与 Sass 类似。
1 | nav { |
3.3.3 混合器 (Mixins)
使用类选择器或 ID 选择器作为 Mixin,直接在其他选择器中引入。可以接受参数。
1 | .border-radius(@radius: 5px) { // 默认参数 |
注意: Less 的 Mixin 默认也会将 Mixin 自身编译为 CSS。如果不想生成多余的 CSS,可以使用 () 或 -- 后缀来定义静默 Mixin。
1 | .my-mixin() { // 静默 Mixin,不会被编译到 CSS |
3.3.4 继承 (:extend)
Less 使用 :extend 伪类进行继承,通常更倾向于使用 Mixins。
1 | .message { |
3.3.5 函数 (Functions)
Less 也提供了各种内建函数(如颜色函数 darken(), lighten(), 数学函数 round(), 字符串函数 e() 等),并支持自定义函数。
1 | @fn-column-width(@total-width, @columns, @gutter) { |
3.3.6 控制指令 (Guard)
Less 没有 @if, @for, @each 等指令,但可以通过 Guard (类似于 Sass 的 if 混合器) 和循环 Mixin 来实现类似逻辑。
1 | // 模拟条件判断 (Guard) |
3.3.7 模块化 (@import)
与 Sass 类似,但 Less 默认会尝试导入 .less 文件,也可以导入 .css 等其他文件。
1 | @import 'base.less'; |
四、Sass 与 Less 的异同
| 特性/Poin ts | Sass / SCSS | Less |
|---|---|---|
| 语法 | .scss 像 CSS,.sass 是缩进语法 |
像 CSS,更简洁,但也支持一些可选的省略 |
| 变量 | $variable-name |
@variable-name |
| Mixin | @mixin name { ... } / @include name |
.name() { ... } / .name; (或 .name()) |
| Extend | @extend .selector |
&:extend(.selector) |
| 嵌套 | 支持,& 代表父选择器 |
支持,& 代表父选择器 |
| 函数 | 丰富内置函数,可自定义 @function |
丰富内置函数,可自定义 (通过 Mixins 或 Less.js API) |
| 条件/循环 | @if, @for, @each, @while |
通过 Guard 和递归 Mixins 模拟 |
| 实现语言 | Ruby Sass (deprecated), Dart Sass (主流,推荐) | JavaScript |
| 编译环境 | Node.js (Dart Sass), 各种构建工具 | Node.js, 浏览器, 各种构建工具 |
| 生态 | 庞大,有 Compass 等框架,社区活跃 | 活跃,但相对 Sass 略小 |
| 学习曲线 | SCSS 接近 CSS,易上手;Sass 缩进语法需适应 | 接近 CSS,易上手 |
共同点
- 都提供了嵌套、变量、混合 (Mixins)、导入 (Import) 等核心功能。
- 都支持算术运算和各种内置函数(颜色处理、数学运算等)。
- 都致力于提高 CSS 的编写效率和可维护性。
- 都与现代前端构建工具链(Webpack, Gulp, Grunt)无缝集成。
主要差异
- 语法:Sass 有两种语法(SCSS 兼容 CSS,Sass 缩进),Less 只有一种类似 CSS 的语法。SCSS 和 Less 在语法上非常接近。
- 变量前缀:Sass 使用
$,Less 使用@。 - Mixin 的实现和调用:Sass 使用
@mixin/@include,Less 使用类选择器或 ID 选择器作为 Mixin。 - 逻辑控制:Sass 提供了更强大的
@if,@for,@each等指令,Less 主要通过 Guard 和递归 Mixins 来实现条件和循环逻辑。 - 核心实现语言:Sass (Dart Sass) 基于 Dart,Less 基于 JavaScript。这意味着 Less 可以直接在浏览器端运行(虽然不推荐用于生产环境)。
- 生态系统:Sass 的生态系统(特别是工具和社区)相对更庞大和成熟。
五、如何选择?
- 如果你追求最新最强大的功能和最活跃的社区:Sass (SCSS) 是首选。它拥有更完善的功能集和更丰富的第三方库。
- 如果你希望与现有 CSS 更高的兼容性,或需要在 Node.js / 浏览器端进行编译:Less 是一个不错的选择,它的语法简洁且接近原生 CSS。
- 如果你团队已经有特定技术栈:遵循团队规范,沿用现有技术栈。
无论是 Sass 还是 Less,它们都是现代前端开发中不可或缺的工具。掌握其中之一,都能显著提升你的 CSS 开发体验。
六、结语
Sass 和 Less 都极大地革新了 CSS 的编写方式,将传统的样式表变成了功能丰富的编程语言。它们通过变量、混合、嵌套等特性,解决了原生 CSS 在大型项目中的痛点,使得 CSS 代码更加模块化、可复用和易于维护。选择哪一个取决于个人偏好、项目需求以及团队的技术栈,但无论选择哪个,都能让你的前端开发工作事半功倍。
