变量

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

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

¥A variable declaration looks a lot like a property declaration: it’s written <variable>: <expression>. Unlike a property, which can only be declared in a style rule or at-rule, variables can be declared anywhere you want. To use a variable, just include it in a value.

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 变量完全不同。了解差异!

¥CSS has variables of its own, which are totally different than Sass variables. Know the differences!

  • Sass 变量全部由 Sass 编译掉。CSS 变量包含在 CSS 输出中。

    ¥Sass variables are all compiled away by Sass. CSS variables are included in the CSS output.

  • CSS 变量对于不同的元素可以有不同的值,但 Sass 变量一次只能有一个值。

    ¥CSS variables can have different values for different elements, but Sass variables only have one value at a time.

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

    ¥Sass variables are imperative, which means if you use a variable and then change its value, the earlier use will stay the same. CSS variables are declarative, which means if you change the value, it’ll affect both earlier uses and later uses.

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 的语法,两者就变得等效以使迁移更容易。

¥Sass variables, like all Sass identifiers, treat hyphens and underscores as identical. This means that $font-size and $font_size both refer to the same variable. This is a historical holdover from the very early days of Sass, when it only allowed underscores in identifier names. Once Sass added support for hyphens to match CSS’s syntax, the two were made equivalent to make migration easier.

默认值默认值 permalink

¥Default Values

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

¥Normally when you assign a value to a variable, if that variable already had a value, its old value is overwritten. But if you’re writing a Sass library, you might want to allow your users to configure your library’s variables before you use them to generate CSS.

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

¥To make this possible, Sass provides the !default flag. This assigns a value to a variable only if that variable isn’t defined or its value is null. Otherwise, the existing value will be used.

配置模块配置模块 permalink

¥Configuring Modules

兼容性:
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

¥Variables defined with !default can be configured when loading a module with the @use rule. Sass libraries often use !default variables to allow their users to configure the library’s CSS.

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

¥To load a module with configuration, write @use <url> with (<variable>: <value>, <variable>: <value>). The configured values will override the variables’ default values. Only variables written at the top level of the stylesheet with a !default flag can be configured.

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

¥Built-in Variables

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

¥Variables that are defined by a built-in module cannot be modified.

Playground

SCSS Syntax

@use "sass:math" as math;

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

Sass Syntax

@use "sass:math" as math

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

范围范围 permalink

¥Scope

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

¥Variables declared at the top level of a stylesheet are global. This means that they can be accessed anywhere in their module after they’ve been declared. But that’s not true for all variables. Those declared in blocks (curly braces in SCSS or indented code in Sass) are usually local, and can only be accessed within the block they were declared.

Playground

SCSS Syntax

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

Sass Syntax

$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

CSS Output

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

.sidebar {
  global: global value;
}






影子影子 permalink

¥Shadowing

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

¥Local variables can even be declared with the same name as a global variable. If this happens, there are actually two different variables with the same name: one local and one global. This helps ensure that an author writing a local variable doesn’t accidentally change the value of a global variable they aren’t even aware of.

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



如果你需要在本地范围内(例如在 mixin 中)设置全局变量的值,则可以使用 !global 标志。标记为 !global 的变量声明将始终分配给全局作用域。

¥If you need to set a global variable’s value from within a local scope (such as in a mixin), you can use the !global flag. A variable declaration flagged as !global will always assign to the global scope.

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!

兼容性:
Dart Sass
since 2.0.0
LibSass
Ruby Sass
Older Sass versions allowed `!global` to be used for a variable that doesn't
exist yet. This behavior was deprecated to make sure each stylesheet
declares the same variables no matter how it's executed.

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

¥The !global flag may only be used to set a variable that has already been declared at the top level of a file. It may not be used to declare a new variable.

流程控制范围流程控制范围 permalink

¥Flow Control Scope

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

¥Variables declared in flow control rules have special scoping rules: they don’t shadow variables at the same level as the flow control rule. Instead, they just assign to those variables. This makes it much easier to conditionally assign a value to a variable, or build up a value as part of a loop.

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!

流控制作用域中的变量可以分配给外部作用域中的现有变量,但在流控制作用域中声明的新变量将无法在外部作用域中访问。确保在分配变量之前已经声明了该变量,即使你需要将其声明为 null

¥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.

高级变量函数高级变量函数 permalink

¥Advanced Variable Functions

Sass 核心库提供了一些用于处理变量的高级函数。meta.variable-exists() 函数 返回给定名称的变量是否存在于当前作用域中,meta.global-variable-exists() 函数 执行相同的操作,但仅适用于全局作用域。

¥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!

用户有时希望使用插值来根据另一个变量定义变量名称。Sass 不允许这样做,因为这使得很难一眼看出哪些变量是在哪里定义的。不过,你可以做的是定义一个从名称到值的 映射,然后你可以使用变量进行访问。

¥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;
}