@function

函数允许你在 SassScript 值 上定义复杂的操作,你可以在整个样式表中重复使用这些操作。它们可以轻松地以可读的方式抽象出常见的公式和行为。

函数是使用 @function at 规则定义的,写作 @function <name>(<arguments...>) { ... }。函数的名称可以是任何不以 -- 开头的 Sass 标识符。它只能包含 普遍陈述 以及 @return 规则(指示用作函数调用结果的值)。使用普通 CSS 函数语法调用函数。

¥Functions are defined using the @function at-rule, which is written @function <name>(<arguments...>) { ... }. A function’s name can be any Sass identifier that doesn’t begin with --. It can only contain universal statements, as well as the @return at-rule which indicates the value to use as the result of the function call. Functions are called using the normal CSS function syntax.

Playground

SCSS Syntax

@function fibonacci($n) {
  $sequence: 0 1;
  @for $_ from 1 through $n {
    $new: nth($sequence, length($sequence)) + nth($sequence, length($sequence) - 1);
    $sequence: append($sequence, $new);
  }
  @return nth($sequence, length($sequence));
}

.sidebar {
  float: left;
  margin-left: fibonacci(4) * 1px;
}
Playground

Sass Syntax

@function fibonacci($n)
  $sequence: 0 1
  @for $_ from 1 through $n
    $new: nth($sequence, length($sequence)) + nth($sequence, length($sequence) - 1)
    $sequence: append($sequence, $new)
  @return nth($sequence, length($sequence))

.sidebar
  float: left
  margin-left: fibonacci(4) * 1px



CSS Output

.sidebar {
  float: left;
  margin-left: 5px;
}









💡 Fun fact:

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

¥Function names, like all Sass identifiers, treat hyphens and underscores as identical. This means that scale-color and scale_color both refer to the same function. 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.

⚠️ Heads up!

虽然从技术上讲函数可能会产生像设置 全局变量 这样的副作用,但强烈建议不要这样做。使用 混入 来产生副作用,并使用函数来计算值。

¥While it’s technically possible for functions to have side-effects like setting global variables, this is strongly discouraged. Use mixins for side-effects, and use functions just to compute values.

参数参数 permalink

¥Arguments

¥

参数允许调用函数 ’每次他们的行为都要定制’。参数在 @function 规则中在函数名称之后指定,作为用括号括起来的变量名称列表。该函数必须使用 SassScript 表达式 形式的相同数量的参数来调用。这些表达式的值可在函数体内作为相应的变量使用。

¥Arguments allow functions’ behavior to be customized each time they’re called. The arguments are specified in the @function rule after the function’s name, as a list of variable names surrounded by parentheses. The function must be called with the same number of arguments in the form of SassScript expressions. The values of these expression are available within the function’s body as the corresponding variables.

💡 Fun fact:

参数列表也可以有尾随逗号!这使得在重构样式表时更容易避免语法错误。

¥Argument lists can also have trailing commas! This makes it easier to avoid syntax errors when refactoring your stylesheets.

可选参数可选参数 permalink

¥Optional Arguments

通常,函数声明的每个参数在包含该函数时都必须传递。但是,你可以通过定义默认值来使参数可选,如果未传递该参数,则将使用该默认值。默认值使用与 变量声明 相同的语法:变量名,后跟冒号和 SassScript 表达式。这使得定义可以简单或复杂方式使用的灵活函数 API 变得容易。

¥Normally, every argument a function declares must be passed when that function is included. However, you can make an argument optional by defining a default value which will be used if that arguments isn’t passed. Default values use the same syntax as variable declarations: the variable name, followed by a colon and a SassScript expression. This makes it easy to define flexible function APIs that can be used in simple or complex ways.

Playground

SCSS Syntax

@function invert($color, $amount: 100%) {
  $inverse: change-color($color, $hue: hue($color) + 180);
  @return mix($inverse, $color, $amount);
}

$primary-color: #036;
.header {
  background-color: invert($primary-color, 80%);
}
Playground

Sass Syntax

@function invert($color, $amount: 100%)
  $inverse: change-color($color, $hue: hue($color) + 180)
  @return mix($inverse, $color, $amount)


$primary-color: #036
.header
  background-color: invert($primary-color, 80%)

CSS Output

.header {
  background-color: rgb(81.6, 51, 20.4);
}






💡 Fun fact:

默认值可以是任何 SassScript 表达式,它们甚至可以引用之前的参数!

¥Default values can be any SassScript expression, and they can even refer to earlier arguments!

关键字参数关键字参数 permalink

¥Keyword Arguments

调用函数时,除了按参数列表中的位置传递参数之外,还可以按名称传递参数。这对于具有多个可选参数的函数或具有 布尔值 参数的函数特别有用,这些参数的含义在没有名称的情况下并不明显。关键字参数使用与 变量声明可选参数 相同的语法。

¥When a function is called, arguments can be passed by name in addition to passing them by their position in the argument list. This is especially useful for functions with multiple optional arguments, or with boolean arguments whose meanings aren’t obvious without a name to go with them. Keyword arguments use the same syntax as variable declarations and optional arguments.

Playground

SCSS Syntax

$primary-color: #036;
.banner {
  background-color: $primary-color;
  color: scale-color($primary-color, $lightness: +40%);
}
Playground

Sass Syntax

$primary-color: #036
.banner
  background-color: $primary-color
  color: scale-color($primary-color, $lightness: +40%)

CSS Output

.banner {
  background-color: #036;
  color: rgb(10.2, 132.6, 255);
}

⚠️ Heads up!

因为任何参数都可以通过名称传递,所以重命名函数的参数时要小心……它可能会破坏你的用户!将旧名称保留为 可选参数 一段时间并在有人通过时打印 警告 会很有帮助,这样他们就知道要迁移到新参数。

¥Because any argument can be passed by name, be careful when renaming a function’s arguments… it might break your users! It can be helpful to keep the old name around as an optional argument for a while and printing a warning if anyone passes it, so they know to migrate to the new argument.

采取任意参数采取任意参数 permalink

¥Taking Arbitrary Arguments

有时,函数能够接受任意数量的参数是很有用的。如果 @function 声明中的最后一个参数以 ... 结尾,则该函数的所有额外参数都将作为 列表 传递给该参数。该参数被称为 参数列表

¥Sometimes it’s useful for a function to be able to take any number of arguments. If the last argument in a @function declaration ends in ..., then all extra arguments to that function are passed to that argument as a list. This argument is known as an argument list.

Playground

SCSS Syntax

@function sum($numbers...) {
  $sum: 0;
  @each $number in $numbers {
    $sum: $sum + $number;
  }
  @return $sum;
}

.micro {
  width: sum(50px, 30px, 100px);
}
Playground

Sass Syntax

@function sum($numbers...)
  $sum: 0
  @each $number in $numbers
    $sum: $sum + $number

  @return $sum


.micro
  width: sum(50px, 30px, 100px)

CSS Output

.micro {
  width: 180px;
}








采用任意关键字参数采用任意关键字参数 permalink

¥Taking Arbitrary Keyword Arguments

参数列表也可用于获取任意关键字参数。meta.keywords() 函数 接受参数列表并返回作为 映射 从参数名称(不包括 $)到这些参数值传递给函数的任何额外关键字。

¥Argument lists can also be used to take arbitrary keyword arguments. The meta.keywords() function takes an argument list and returns any extra keywords that were passed to the function as a map from argument names (not including $) to those arguments’ values.

💡 Fun fact:

如果你从未将参数列表传递给 meta.keywords() 函数,则该参数列表将不允许额外的关键字参数。这可以帮助函数的调用者确保他们没有意外拼错任何参数名称。

¥If you don’t ever pass an argument list to the meta.keywords() function, that argument list won’t allow extra keyword arguments. This helps callers of your function make sure they haven’t accidentally misspelled any argument names.

传递任意参数传递任意参数 permalink

¥Passing Arbitrary Arguments

就像参数列表允许函数采用任意位置或关键字参数一样,可以使用相同的语法将位置和关键字参数传递给函数。如果传递一个列表,后跟 ... 作为函数调用的最后一个参数,则其元素将被视为附加位置参数。同样,后面跟着 ... 的映射将被视为附加关键字参数。你甚至可以同时通过两者!

¥Just like argument lists allow functions to take arbitrary positional or keyword arguments, the same syntax can be used to pass positional and keyword arguments to a function. If you pass a list followed by ... as the last argument of a function call, its elements will be treated as additional positional arguments. Similarly, a map followed by ... will be treated as additional keyword arguments. You can even pass both at once!

Playground

SCSS Syntax

$widths: 50px, 30px, 100px;
.micro {
  width: min($widths...);
}
Playground

Sass Syntax

$widths: 50px, 30px, 100px
.micro
  width: min($widths...)

CSS Output

.micro {
  width: 30px;
}

💡 Fun fact:

由于 参数列表 会跟踪位置参数和关键字参数,因此你可以使用它将两者同时传递给另一个函数。这使得为函数定义别名变得非常容易!

¥Because an argument list keeps track of both positional and keyword arguments, you use it to pass both at once to another function. That makes it super easy to define an alias for a function!

Playground

SCSS Syntax

@function fg($args...) {
  @warn "The fg() function is deprecated. Call foreground() instead.";
  @return foreground($args...);
}
Playground

Sass Syntax

@function fg($args...)
  @warn "The fg() function is deprecated. Call foreground() instead."
  @return foreground($args...)

@return@return permalink

@return at 规则指示用作调用函数结果的值。仅允许在 @function 主体内使用,并且每个 @function 必须以 @return 结尾。

¥The @return at-rule indicates the value to use as the result of calling a function. It’s only allowed within a @function body, and each @function must end with a @return.

当遇到 @return 时,它立即结束函数并返回结果。提前返回对于处理边缘情况或无需将整个函数封装在 @else 中即可使用更有效算法的情况很有用。

¥When a @return is encountered, it immediately ends the function and returns its result. Returning early can be useful for handling edge-cases or cases where a more efficient algorithm is available without wrapping the entire function in an @else block.

Playground

SCSS Syntax

@use "sass:string";

@function str-insert($string, $insert, $index) {
  // Avoid making new strings if we don't need to.
  @if string.length($string) == 0 {
    @return $insert;
  }

  $before: string.slice($string, 0, $index);
  $after: string.slice($string, $index);
  @return $before + $insert + $after;
}
Playground

Sass Syntax

@use "sass:string"

@function str-insert($string, $insert, $index)
  // Avoid making new strings if we don't need to.
  @if string.length($string) == 0
    @return $insert


  $before: string.slice($string, 0, $index)
  $after: string.slice($string, $index)
  @return $before + $insert + $after

其他函数其他函数 permalink

¥Other Functions

除了用户定义的函数之外,Sass 还提供了大量始终可用的内置函数。Sass 实现还可以在宿主语言中定义 自定义功能。当然,你可以随时调用 CSS 函数(甚至调用 奇怪的语法)。

¥In addition to user-defined function, Sass provides a substantial core library of built-in functions that are always available to use. Sass implementations also make it possible to define custom functions in the host language. And of course, you can always call plain CSS functions (even ones with weird syntax).

CSS 函数CSS 函数 permalink

¥Plain CSS Functions

任何既不是用户定义函数也不是 内置的 函数的函数调用都会编译为普通 CSS 函数(除非它使用 Sass 参数语法)。参数将被编译为 CSS 并按原样包含在函数调用中。这确保了 Sass 支持所有 CSS 功能,而无需每次添加新版本时都发布新版本。

¥Any function call that’s not either a user-defined or built-in function is compiled to a plain CSS function (unless it uses Sass argument syntax). The arguments will be compiled to CSS and included as-is in the function call. This ensures that Sass supports all CSS functions without needing to release new versions every time a new one is added.

Playground

SCSS Syntax

@debug var(--main-bg-color); // var(--main-bg-color)

$primary: #f2ece4;
$accent: #e1d7d2;
@debug radial-gradient($primary, $accent); // radial-gradient(#f2ece4, #e1d7d2)
Playground

Sass Syntax

@debug var(--main-bg-color)  // var(--main-bg-color)

$primary: #f2ece4
$accent: #e1d7d2
@debug radial-gradient($primary, $accent)  // radial-gradient(#f2ece4, #e1d7d2)

⚠️ Heads up!

因为任何未知的函数都会被编译为 CSS,所以当你输入错误的函数名称时很容易遗漏。考虑在样式表的输出上运行 CSS linter,以便在发生这种情况时收到通知!

¥Because any unknown function will be compiled to CSS, it’s easy to miss when you typo a function name. Consider running a CSS linter on your stylesheet’s output to be notified when this happens!

💡 Fun fact:

某些 CSS 函数(例如 calc()element())具有不寻常的语法。Sass 专门解析这些函数不带引号的字符串

¥Some CSS functions, like calc() and element() have unusual syntax. Sass parses these functions specially as unquoted strings.