计算是 Sass 如何表示 calc()
函数,以及类似的函数,如 clamp()
、min()
和 max()
。 Sass 会尽可能地简化这些,即使它们是相互结合的。
LibSass、Ruby Sass 和 Dart Sass 1.40.0 之前的版本将 calc() 解析为像 element() 一样的特殊函数。
LibSass、Ruby Sass 和 Dart Sass 1.31.0 之前的版本将 clamp() 解析为纯 CSS 函数,而不是在其中支持特殊语法。 1.31.0 和 1.40.0 之间的 Dart Sass 版本将 clamp() 解析为像 element() 一样的特殊函数。
@debug calc(400px + 10%); // calc(400px + 10%)
@debug calc(400px / 2); // 200px
@debug min(100px, calc(1rem + 10%)); // min(100px, 1rem + 10%)
计算使用不同于普通 SassScript 的特殊语法。 它的语法与 CSS calc()
相同,但具有使用 Sass 变量 和调用 Sass 函数 的附加功能。 这意味着 /
始终是计算中的除法运算符!
💡 有趣的事实:
Sass 函数调用的参数使用普通的 Sass 语法,而不是特殊的计算语法!
您还可以在计算中使用 interpolation。 但是,如果您这样做,插值周围的括号中的任何内容都不会被简化或进行类型检查,因此很容易导致额外冗长甚至无效的 CSS。 与其写 calc(10px + #{$var})
,不如写 calc(10px + $var)
!
简化
如果 Sass 使用可以在编译时组合的单位,例如 1in + 10px
或 5s * 2
,Sass 将简化计算中的相邻操作。 如果可能,它甚至会将整个计算简化为一个数字——例如,clamp(0px, 30px, 20px)
将返回 20px
。
⚠️ 注意!
这意味着计算表达式不一定总是返回计算! 如果您正在编写 Sass 库,您始终可以使用 meta.type-of()
函数来确定您正在处理的类型。
计算也将在其他计算中得到简化。 特别是,如果 calc()
最终出现在任何其他计算中,函数调用将被删除,并将被一个普通的旧操作所取代。
$width: calc(400px + 10%);
.sidebar {
width: $width;
padding-left: calc($width / 4);
}
操作
您不能将计算与正常的 SassScript 操作一起使用,例如 +
和 *
。 如果您想编写一些允许计算的数学函数,只需将它们写在它们自己的 calc()
表达式中——如果它们传递了一堆具有兼容单位的数字,它们也会返回纯数字,如果它们 重新通过计算,他们将返回计算。
实施此限制是为了确保如果不需要计算,它们会尽快抛出错误。 计算不能用在纯数字可以用的所有地方:例如,它们不能注入 CSS 标识符(例如 .item-#{$n}`),也不能传递给 Sass 的内置 数学函数。 为纯数字保留 SassScript 操作可以明确哪些地方允许计算,哪些地方不允许。
$width: calc(100% + 10px);
@debug $width * 2; // Error!
@debug calc($width * 2); // calc((100% + 10px) * 2);
常量
Compatibility: Dart Sass since 1.60.0 | LibSass ✗ | Ruby Sass ✗
计算还可以包含常量,这些常量被写为 CSS 标识符。 为了与未来的 CSS 规范向前兼容,all 标识符是允许的,默认情况下它们只是被视为按原样传递的不带引号的字符串。
@debug calc(h + 30deg); // calc(h + 30deg);
Sass 自动将 CSS 中指定的一些特殊常量名称解析为无单位数字:
@use 'sass:math';
@debug calc(pi); // 3.1415926536
@debug calc(e); // 2.7182818285
@debug calc(infinity) > math.$max-number; // true
@debug calc(-infinity) < math.$min-number; // true
min() and max()
兼容性(特殊函数语法): Dart Sass since >=1.11.0 <1.42.0
| LibSass ✗ | Ruby Sass ✗
LibSass、Ruby Sass 和 Dart Sass 1.11.0 之前的版本总是将 min() 和 max() 解析为 Sass 函数。 要为这些实现创建纯 CSS min() 或 max() 调用,您可以改为编写类似 unquote("min(#{$padding}, env(safe-area-inset-left))") 的内容。
1.11.0 和 1.40.0 之间以及 1.40.1 和 1.42.0 之间的 Dart Sass 版本将 min() 和 max() 函数解析为特殊函数,如果它们是有效的纯 CSS,但将它们解析为 Sass 函数,如果它们 包含插值以外的 Sass 特性,如变量或函数调用。
Dart Sass 1.41.0 将 min() 和 max() 函数解析为计算,但不允许无单位数字与带单位的数字组合。 这与全局 min() 和 max() 函数向后不兼容,因此该行为已恢复。
CSS 在值和单位第 4 级中添加了对 min()
和 max()
函数 的支持,从那里开始 很快被 Safari 采用 以支持 iPhoneX。 但是 Sass 早在这之前就支持自己的 min()
和 max()
函数,并且 它需要向后兼容所有那些现有的样式表。 这导致需要特别的句法技巧。
如果 min()
或 max()
函数调用是有效的计算表达式,它将被解析为计算。 但是只要调用的任何部分包含计算中不支持的 SassScript 功能,例如 modulo operator,它就会被解析为对 Sass 核心 min( )
或 max()
函数代替。
由于无论如何都尽可能将计算简化为数字,唯一实质性的区别是 Sass 函数仅支持可以在构建时组合的单位,因此 min(12px % 10, 10%) 会抛出错误。
⚠️ 注意!
其他计算不允许无单位数字与有单位的数字相加、相减或比较。 但是,min()
和 max()
是不同的:为了向后兼容全局 Sass min()
和 max()
函数,由于历史原因允许单位/无单位混合,这些单位可以是 混合,只要它们直接包含在 min()
或 max()
计算中。
$padding: 12px;
.post {
// Since these max() calls are valid calculation expressions, they're
// parsed as calculations.
padding-left: max($padding, env(safe-area-inset-left));
padding-right: max($padding, env(safe-area-inset-right));
}
.sidebar {
// Since these use the SassScript-only modulo operator, they're parsed as
// SassScript function calls.
padding-left: max($padding % 10, 20px);
padding-right: max($padding % 10, 20px);
}