函数 @function

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

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

scss
Scss
scss
@function pow($base, $exponent) {
  $result: 1;
  @for $_ from 1 through $exponent {
    $result: $result * $base;
  }
  @return $result;
}

.sidebar {
  float: left;
  margin-left: pow(4, 3) * 1px;
}

💡 有趣的事实:

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

⚠️ 注意!

虽然从技术上讲,函数可能会产生副作用,例如设置 global variables,但强烈建议不要这样做。 使用 mixins 来产生副作用,并使用函数来计算值。

参数

参数允许在每次调用函数时自定义函数的行为。 参数在函数名称后的@function规则中指定为用括号括起来的变量名称列表。 该函数必须以 SassScript 表达式 的形式使用相同数量的参数调用。 这些表达式的值在函数体中作为相应的变量可用。

💡 有趣的事实:

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

可选参数

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

scss
Scss
scss
@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%);
}

💡 有趣的事实:

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

关键字参数

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

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

⚠️ 注意!

因为 any 参数可以按名称传递,所以在重命名函数的参数时要小心……它可能会破坏您的用户! 将旧名称作为 optional argument 保留一段时间并打印 [warning](/at-rules /warn) 如果有人通过它,那么他们就知道要迁移到新参数。

任意参数

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

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

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

接受任意关键字参数

参数列表也可用于获取任意关键字参数。 meta.keywords() 函数 接受一个参数列表并返回作为 map 从参数名称(不包括 $)到这些参数的值。

💡 有趣的事实:

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

传递任意参数

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

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

💡 有趣的事实:

因为 argument list 跟踪位置参数和关键字参数,所以您可以使用它同时将两者传递给另一个函数。 这使得为函数定义别名变得非常容易!

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

@return

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

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

scss
Scss
scss
@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;
}

其他函数

除了用户定义的函数之外,Sass 还提供了一个庞大的核心库 内置函数,随时可用。 Sass 实现还可以在宿主语言中定义自定义函数。 当然,您始终可以调用 纯 CSS 函数(即使是具有 奇怪语法).

纯 CSS 函数

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

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

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

⚠️ 注意!

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

💡 有趣的事实: 一些 CSS 函数,如 calc()element() 具有不寻常的语法。 Sass 专门将这些函数解析为不带引号的字符串。