变量

Sass 变量很简单:你将一个值赋给以 $ 开头的名称,然后可以引用该名称而不是值本身。尽管它们很简单, 但它们是 Sass 带来的最有用的工具之一。变量使得减少重复、进行复杂数学运算、配置库等成为可能。

变量声明看起来很像属性声明:写作 <变量>: <表达式>。与只能在样式规则或 at 规则中声明的属性不同,变量可以在任何你想要的地方声明。要使用变量,只需在值中包含它。

Playground

SCSS Syntax

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

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

Sass Syntax

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

.alert
  border: 1px solid $border-dark

CSS Output

.alert {
  border: 1px solid rgba(198, 83, 140, 0.88);
}



⚠️ Heads up!

CSS自己的变量,它们与 Sass 变量完全不同。请了解它们的区别!

  • Sass 变量会被 Sass 完全编译掉。CSS 变量会包含在 CSS 输出中。

  • CSS 变量可以为不同的元素设置不同的值,但 Sass 变量在同一时间只有一个值。

  • Sass 变量是命令式的,这意味着如果你使用一个变量然后改变其值,早期的使用将保持不变。CSS 变量是声明式的,这意味着如果你改变值,它将影响早期和后续的使用。

Playground

SCSS Syntax

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

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

Sass Syntax

$variable: value 1
.rule-1
  value: $variable


$variable: value 2
.rule-2
  value: $variable

CSS Output

.rule-1 {
  value: value 1;
}

.rule-2 {
  value: value 2;
}


💡 Fun fact:

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

默认值默认值 permalink

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

为了实现这一点,Sass 提供了 !default 标志。这仅在变量未定义或其值为 null 时才为变量赋值。否则,将使用现有值。

配置模块配置模块 permalink

Compatibility:
Dart Sass
since 1.23.0
LibSass
Ruby Sass

Only Dart Sass currently supports @use. Users of other implementations must use the @import rule instead.

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

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

SCSS Syntax

// _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
);

Sass Syntax

// _library.sass
$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.sass
@use 'library' with ($black: #222, $border-radius: 0.1rem)



CSS Output

code {
  border-radius: 0.1rem;
  box-shadow: 0 0.5rem 1rem rgba(34, 34, 34, 0.15);
}












内置变量内置变量 permalink

内置模块定义的变量不能被修改。

Playground

SCSS Syntax

@use "sass:math" as math;

// 这个赋值将失败。
math.$pi: 0;
Playground

Sass Syntax

@use "sass:math" as math

// 这个赋值将失败。
math.$pi: 0

作用域作用域 permalink

在样式表顶层声明的变量是全局的。这意味着它们可以在声明后的模块中的任何地方访问。但并非所有变量都是如此。在块中(SCSS 中的大括号或 Sass 中的缩进代码)声明的变量通常是局部的,只能在声明它们的块内访问。

Playground

SCSS Syntax

$global-variable: global value;

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

.sidebar {
  global: $global-variable;

  // 这将失败,因为 $local-variable 不在作用域内:
  // local: $local-variable;
}
Playground

Sass Syntax

$global-variable: global value

.content
  $local-variable: local value
  global: $global-variable
  local: $local-variable


.sidebar
  global: $global-variable

  // 这将失败,因为 $local-variable 不在作用域内:
  // local: $local-variable

CSS Output

.content {
  global: global value;
  local: local value;
}

.sidebar {
  global: global value;
}






遮蔽遮蔽 permalink

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

Playground

SCSS Syntax

$variable: global value;

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

.sidebar {
  value: $variable;
}
Playground

Sass Syntax

$variable: global value

.content
  $variable: local value
  value: $variable


.sidebar
  value: $variable

CSS Output

.content {
  value: local value;
}

.sidebar {
  value: global value;
}



如果你需要在局部作用域(如在混入中)设置全局变量的值,可以使用 !global 标志。带有 !global 标志的变量声明将始终赋值到全局作用域。

Playground

SCSS Syntax

$variable: first global value;

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

.sidebar {
  value: $variable;
}
Playground

Sass Syntax

$variable: first global value

.content
  $variable: second global value !global
  value: $variable


.sidebar
  value: $variable

CSS Output

.content {
  value: second global value;
}

.sidebar {
  value: second global value;
}



⚠️ Heads up!

Compatibility:
Dart Sass
since 2.0.0
LibSass
Ruby Sass

旧版 Sass 允许对尚未存在的变量使用 !global。这种行为已被弃用,以确保每个样式表无论如何执行都声明相同的变量。

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

流程控制作用域流程控制作用域 permalink

流程控制规则中声明的变量有特殊的作用域规则:它们不会遮蔽与流程控制规则处于同一级别的变量。相反,它们只是为这些变量赋值。这使得有条件地为变量赋值,或作为循环的一部分构建值变得更加容易。

Playground

SCSS Syntax

$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;
}
Playground

Sass Syntax

$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

CSS Output

.button {
  background-color: rgb(116.96, 12.04, 48.16);
  border: 1px solid rgb(245.4696132597, 235.4309392265, 251.5690607735);
  border-radius: 3px;
}









⚠️ Heads up!

Variables in flow control scope can assign to existing variables in the outer scope, but new variables declared in flow control scope won’t be accessible in the outer scope. Make sure the variable is already declared before you assign to it, even if you need to declare it as null.

Advanced Variable FunctionsAdvanced Variable Functions permalink

The Sass core library provides a couple advanced functions for working with variables. The meta.variable-exists() function returns whether a variable with the given name exists in the current scope, and the meta.global-variable-exists() function does the same but only for the global scope.

⚠️ Heads up!

Users occasionally want to use interpolation to define a variable name based on another variable. Sass doesn’t allow this, because it makes it much harder to tell at a glance which variables are defined where. What you can do, though, is define a map from names to values that you can then access using variables.

Playground

SCSS Syntax

@use "sass:map";

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

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

Sass Syntax

@use "sass:map"

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

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





CSS Output

.alert {
  background-color: #ffc107;
}