变量 Variables

您将一个值赋给以“$”开头的名称,然后您可以引用该名称而不是该值本身。

Sass 变量很简单: 尽管它们很简单,但它们是 Sass 带来的最有用的工具之一。 变量可以减少重复、进行复杂的数学运算、配置库等等。

变量声明看起来很像 属性声明:它被写成<variable>: <expression>。 与只能在样式规则或 at 规则中声明的属性不同,变量可以在您想要的任何地方声明。 要使用变量,只需将其包含在值中即可。

scss
Scss
scss
$base-color: #c6538c;
$border-dark: rgba($base-color, 0.88);

.alert {
  border: 1px solid $border-dark;
}

⚠️ 注意!

CSS 有自己的变量,这与 Sass 变量完全不同。 了解差异!

  • Sass 变量全部由 Sass 编译掉。 CSS 变量包含在 CSS 输出中。
  • CSS 变量对于不同的元素可以有不同的值,但 Sass 变量一次只有一个值。
  • Sass 变量是_imperative_,这意味着如果你使用一个变量然后改变它的值,之前的使用将保持不变。 CSS 变量是_declarative_,这意味着如果您更改值,它会影响早期使用和以后使用。
scss
Scss
scss
$variable: value 1;
.rule-1 {
  value: $variable;
}

$variable: value 2;
.rule-2 {
  value: $variable;
}

💡 有趣的事实:

Sass 变量和所有 Sass 标识符一样,将连字符和下划线视为相同。 这意味着 $font-size$font_size 都引用同一个变量。 这是 Sass 早期的历史遗留问题,当时它_只_允许在标识符名称中使用下划线。 一旦 Sass 添加了对连字符的支持以匹配 CSS 的语法,这两者就变得等效,从而使迁移更容易。

默认值

通常,当您为变量赋值时,如果该变量已经有一个值,它的旧值将被覆盖。 但是,如果您正在编写 Sass 库,您可能希望允许您的用户在您使用它们生成 CSS 之前配置您的库的变量。

为了使这成为可能,Sass 提供了 !default 标志。 这会为变量赋值_仅当_该变量未定义或其值为 null 时。 否则,将使用现有值。

配置模块

Compatibility: Dart Sass since 1.23.0 | LibSass ✗ | Ruby Sass ✗

目前只有 Dart Sass 支持@use。 其他实现的用户必须改用@import 规则。

使用 @use 规则 加载模块时,可以配置使用 !default 定义的变量。 Sass 库通常使用 !default 变量来允许其用户配置库的 CSS。

要使用配置加载模块,请编写@use <url> with (<variable>: <value>, <variable>: <value>)。 配置的值将覆盖变量的默认值。 只能配置在样式表顶层带有 !default 标志的变量。

scss
Scss
scss
// _library.scss
$black: #000 !default;
$border-radius: 0.25rem !default;
$box-shadow: 0 0.5rem 1rem rgba($black, 0.15) !default;

code {
  border-radius: $border-radius;
  box-shadow: $box-shadow;
}
// style.scss
@use 'library' with (
  $black: #222,
  $border-radius: 0.1rem
);

内置变量

无法修改由 内置模块 定义的变量。

scss
Scss
scss
@use "sass:math" as math;

// This assignment will fail.
math.$pi: 0;

Scope

在样式表的顶层声明的变量是 global。 这意味着它们在声明后可以在模块中的任何位置访问。 但并非所有变量都如此。 那些在块中声明的(SCSS 中的大括号或 Sass 中的缩进代码)通常是 local,并且只能在它们被声明的块中访问。

scss
Scss
scss
$global-variable: global value;

.content {
  $local-variable: local value;
  global: $global-variable;
  local: $local-variable;
}

.sidebar {
  global: $global-variable;

  // This would fail, because $local-variable isn't in scope:
  // local: $local-variable;
}

Shadowing

局部变量甚至可以用与全局变量相同的名称来声明。 如果发生这种情况,实际上有两个同名的不同变量:一个局部变量和一个全局变量。 这有助于确保编写局部变量的作者不会意外更改他们甚至不知道的全局变量的值。

scss
Scss
scss
$variable: global value;

.content {
  $variable: local value;
  value: $variable;
}

.sidebar {
  value: $variable;
}

如果您需要在局部范围内(例如在混入中)设置全局变量的值,则可以使用 !global 标志。 标记为 !global 的变量声明将_总是_分配给全局范围。

scss
Scss
scss
$variable: first global value;

.content {
  $variable: second global value !global;
  value: $variable;
}

.sidebar {
  value: $variable;
}

⚠️ Heads up!

Compatibility: Dart Sass since 2.0.0 | LibSass ✗ | Ruby Sass ✗

较旧的 Sass 版本允许 !global 用于尚不存在的变量。 此行为已被弃用,以确保每个样式表声明相同的变量,无论它如何执行。

!global 标志只能用于设置已在文件顶层声明的变量。 它 不能 用于声明新变量。

流量控制范围

流控制规则 中声明的变量具有特殊的范围规则:它们不会将变量隐藏在与流控制规则相同的级别。 相反,他们只是分配给那些变量。 这使得有条件地为变量赋值或在循环中构建值变得更加容易。

scss
Scss
scss
$dark-theme: true !default;
$primary-color: #f8bbd0 !default;
$accent-color: #6a1b9a !default;

@if $dark-theme {
  $primary-color: darken($primary-color, 60%);
  $accent-color: lighten($accent-color, 60%);
}

.button {
  background-color: $primary-color;
  border: 1px solid $accent-color;
  border-radius: 3px;
}

⚠️ 注意!

流程控制范围内的变量可以赋值给外部范围内的现有变量,但在流程控制范围内声明的新变量将无法在外部范围内访问。 确保变量在赋值之前已经声明,即使您需要将其声明为 null

高级变量函数

Sass 核心库提供了一些用于处理变量的高级函数。 meta.variable-exists() 函数 返回当前范围内是否存在具有给定名称的变量,以及 meta.global-variable -exists() 函数 做同样的事情,但只针对全局范围。

⚠️ 注意!

用户偶尔会希望使用插值来根据另一个变量定义一个变量名。 Sass 不允许这样做,因为它让人更难一眼看出哪些变量定义在哪里。 不过,您 可以 做的是定义一个从名称到值的 map,然后您可以使用变量访问该值。

scss
Scss
scss
@use "sass:map";

$theme-colors: (
  "success": #28a745,
  "info": #17a2b8,
  "warning": #ffc107,
);

.alert {
  // Instead of $theme-color-#{warning}
  background-color: map.get($theme-colors, "warning");
}