Sass/SCSS 预处理器:变量、混入与嵌套

FreeGuideOnline 最新 2026-06-15

初识 Sass/SCSS:CSS 的超级增强

在现代前端开发中,样式表的管理往往比 HTML 结构本身更为复杂。原生的 CSS 缺少变量、复用机制和层级组织能力,导致代码臃肿、维护困难。Sass (Syntactically Awesome Style Sheets) 正是为解决这些问题而生的 CSS 预处理器。它通过引入编程语言特性,让样式编写更高效、更易维护。本教程将聚焦 Sass 最核心的三大特性:变量嵌套混入,带你从零开始掌握这门利器。

安装与编译:让 Sass 运行起来

Sass 无法直接被浏览器解析,需要通过工具将 .scss.sass 文件编译为标准的 .css 文件。推荐使用 npm 安装 Dart Sass(官方推荐版本):

npm install -g sass

编译单个文件:

sass style.scss style.css

监听文件变化并自动编译:

sass --watch input.scss:output.css

现在几乎所有现代构建工具(Webpack、Vite、Gulp)都内置了 Sass 支持,只需安装相应加载器即可无缝集成。接下来,我们深入三大基石特性。


变量:一次定义,全局复用

在原生 CSS 中,重复的颜色值、字体栈或间距数值散落在各处,一旦需要调整,不得不逐个查找替换。Sass 变量让你将这类值抽象为语义化的标识符。

定义与使用变量

变量以 $ 符号开头,赋值语法和 CSS 属性值一样:

// 定义变量
$primary-color: #3498db;
$font-stack: 'Helvetica Neue', sans-serif;
$base-padding: 1rem;

// 使用变量
body {
  font-family: $font-stack;
  color: $primary-color;
  padding: $base-padding;
}

编译后:

body {
  font-family: 'Helvetica Neue', sans-serif;
  color: #3498db;
  padding: 1rem;
}

变量作用域与默认值

Sass 的变量具有块级作用域,但可以通过 !global 声明提升为全局变量。还支持 !default 标记,表示“如果变量未被赋值则使用此默认值”,这对库开发和主题定制极其有用。

$border-radius: 3px !default;

.card {
  $radius: 5px;           // 局部变量
  border-radius: $radius;
}

.footer {
  border-radius: $border-radius;
}

数据类型与插值

Sass 变量不仅能存储颜色、长度,还支持数字、字符串、列表、映射(map)、布尔值等。在字符串中插入变量时,需使用 #{} 插值语法:

$side: left;

.alert-#{$side} {
  border-#{$side}: 3px solid red;
}

编译后:

.alert-left {
  border-left: 3px solid red;
}

合理运用变量,可以让整个样式系统的主题风格、间距、断点等高度统一,修改时只需改动一处。


嵌套:让选择器关系一目了然

CSS 依靠后代选择器来表现层级关系,但书写扁平的选择器无法直观反映 HTML 的嵌套结构。Sass 允许将选择器嵌套在父选择器内部,使代码结构更贴近 DOM 树。

基础选择器嵌套

.nav {
  background: #333;

  ul {
    list-style: none;
    margin: 0;
    padding: 0;
  }

  li {
    display: inline-block;
  }

  a {
    color: white;
    text-decoration: none;
  }
}

编译为:

.nav { background: #333; }
.nav ul { list-style: none; margin: 0; padding: 0; }
.nav li { display: inline-block; }
.nav a { color: white; text-decoration: none; }

父选择器标识符 &

在嵌套中,借助 & 符号引用外层父选择器。这在编写伪类、伪元素或组合选择器时特别有用。

.button {
  background: blue;

  &:hover {
    background: darkblue;
  }

  &.disabled {
    opacity: 0.5;
    cursor: not-allowed;
  }
}

编译后:

.button { background: blue; }
.button:hover { background: darkblue; }
.button.disabled { opacity: 0.5; cursor: not-allowed; }

& 还能巧妙地处理诸如 BEM 命名 或复合选择器:

.block {
  &__element {
    color: red;
  }
  &--modifier {
    font-weight: bold;
  }
}

输出 .block__element.block--modifier,大幅减少重复的类名书写。

属性嵌套与占位符

除了选择器,Sass 还支持将命名空间属性(如 font-family, font-size)进行嵌套书写:

.box {
  font: {
    family: Arial;
    size: 16px;
    weight: bold;
  }
  margin: {
    top: 20px;
    bottom: 10px;
  }
}

编译为常规的连字符属性,提升可读性。注意不要过度嵌套,通常推荐不超过 3 层深度,以保持编译后选择器的精炼。


混入:代码块的终极复用

变量适合存储单一值,而混入(Mixin)可以存储一堆样式规则,并且能接受参数,实现高阶复用。它适用于需要动态生成样式跨多个选择器复用相同逻辑的场景(如清除浮动、媒体查询、主题皮肤)。

定义与使用无参混入

@mixin reset-list {
  margin: 0;
  padding: 0;
  list-style: none;
}

.menu {
  @include reset-list;
}

带参数的混入

参数让混入变得灵活,可以传入值来定制输出。参数支持默认值,调用时可传参或不传。

@mixin box-shadow($x, $y, $blur, $color: rgba(0,0,0,0.3)) {
  box-shadow: $x $y $blur $color;
}

.card {
  @include box-shadow(2px, 4px, 6px);
}
// 编译: box-shadow: 2px 4px 6px rgba(0,0,0,0.3);

.alert {
  @include box-shadow(0, 0, 10px, red);
}
// 编译: box-shadow: 0 0 10px red;

关键字参数与可变参数

调用时可以使用关键字参数,顺序无关,提高可读性:

@include box-shadow($blur: 8px, $x: 1px, $y: 1px, $color: #ccc);

对于参数数量不确定的情况(如多个阴影或过渡值),用 ... 表示可变参数:

@mixin transitions($props...) {
  transition: $props;
}

.btn {
  @include transitions(color 0.3s, background 0.3s, opacity 0.2s);
}

混入中的内容块 @content

使用 @content 指令可以传递整个样式块到混入内部,常用来生成媒体查询包装器或响应式断点。

@mixin respond-to($media) {
  @if $media == phone {
    @media (max-width: 600px) { @content; }
  } @else if $media == tablet {
    @media (max-width: 900px) { @content; }
  }
}

.profile {
  width: 300px;

  @include respond-to(phone) {
    width: 100%;
  }
}

编译后,.profile 的宽度在 600px 以下变为 100%。@content 让混入成为真正的“模板”,将控制逻辑与具体样式解耦。


变量、嵌套与混入协同实战

将三大特性结合,可以构建一套高度可维护的组件样式:

// 变量定义主题
$primary: #2ecc71;
$secondary: #27ae60;
$radius: 6px;

// 混入定义按钮基础
@mixin button-base($bg, $color: white) {
  display: inline-block;
  padding: 0.8em 1.5em;
  border: none;
  border-radius: $radius;
  background: $bg;
  color: $color;
  text-decoration: none;
  cursor: pointer;

  // 嵌套的 hover 状态
  &:hover {
    background: darken($bg, 10%);
  }
  // 通过 @content 允许额外定制
  @content;
}

.btn-primary {
  @include button-base($primary) {
    font-weight: bold;
    text-transform: uppercase;
  }
}

.btn-secondary {
  @include button-base($secondary);
}

输出干净且结构清晰的 CSS,同时保留了极高的可调整性:修改一个变量即可切换主题色彩,调整混入或嵌套即可影响所有相关按钮。


延伸与最佳实践

  • 避免选择器过深:嵌套是双刃剑,超过 3 层往往导致特异性过高和难以覆盖,参考 BEM 等命名约定来保持扁平。
  • 模块化组织:将变量、混入、通用样式拆分为 _variables.scss_mixins.scss_base.scss 等部分文件(Partial),通过 @use@import 加载,提升协作效率。
  • 善用内置函数:Sass 提供了颜色运算、数学计算、列表处理等大量函数(如 darken(), lighten(), rgba(), nth()),与变量结合能动态生成丰富的样式。
  • 谨慎使用混入 vs 占位符 %:当混入不接收参数且生成完全相同的静态代码时,使用 @extend 配合占位符选择器可以避免重复的 CSS 输出,减少文件体积。

掌握了变量、嵌套和混入,你已经拥有了将 CSS 转变为可编程样式系统的能力。从个人项目到大型团队协作,Sass 都能显著提升开发体验,让你的样式表成为逻辑清晰、易于迭代的工程资产。