计算
计算 是 Sass 表示 calc() 函数以及类似函数(如 clamp()、min() 和 max())的方式。Sass 会尽可能地简化这些计算,即使它们相互组合也是如此。
@debug calc(400px + 10%); // calc(400px + 10%)
@debug calc(400px / 2); // 200px
@debug min(100px, calc(1rem + 10%)); // min(100px, 1rem + 10%)
@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 函数的能力。这意味着 / 在计算中始终是除法运算符!
你也可以在计算中使用插值。但是,如果你这样做,任何涉及该插值的操作都将不会被简化或进行类型检查,因此很容易产生冗长甚至无效的 CSS。与其编写 calc(10px + #{$var}),不如直接编写 calc(10px + $var)!
简化
如果计算中相邻的操作使用可以在编译时组合的单位,例如 1in + 10px 或 5s * 2,Sass 将对其进行简化。如果可能,它甚至会将整个计算简化为一个单一的数字——例如,clamp(0px, 30px, 20px) 将返回 20px。
meta.type-of() 函数来确定你正在处理的类型。计算也会在其他计算中被简化。特别是,如果一个 calc() 最终位于任何其他计算内部,该函数调用将被移除,并被替换为一个普通的操作。
$width: calc(400px + 10%);
.sidebar {
width: $width;
padding-left: calc($width / 4);
}
$width: calc(400px + 10%)
.sidebar
width: $width
padding-left: calc($width / 4)
.sidebar {
width: calc(400px + 10%);
padding-left: calc((400px + 10%) / 4);
}
操作
你不能将计算与普通的 SassScript 操作符(如 + 和 *)一起使用。如果你想编写一些允许计算的数学函数,只需在它们自己的 calc() 表达式中编写它们即可——如果它们被传递一堆带有兼容单位的数字,它们也会返回普通数字,如果它们被传递计算,它们会返回计算。
此限制是为了确保如果不需要计算,它们会尽快抛出错误。计算不能在所有可以使用普通数字的地方使用:例如,它们不能被注入到 CSS 标识符(如 .item-#{$n})中,也不能传递给 Sass 的内置数学函数。将 SassScript 操作符保留给普通数字可以清楚地表明计算在哪里被允许,在哪里不被允许。
$width: calc(100% + 10px);
@debug $width * 2; // Error!
@debug calc($width * 2); // calc((100% + 10px) * 2);
$width: calc(100% + 10px);
@debug $width * 2; // Error!
@debug calc($width * 2); // calc((100% + 10px) * 2);
常量
计算还可以包含常量,它们被写成 CSS 标识符。为了与未来的 CSS 规范向前兼容,所有标识符都被允许,默认情况下,它们被视为不带引号的字符串,原样传递。
@debug calc(h + 30deg); // calc(h + 30deg);
@debug calc(h + 30deg) // calc(h + 30deg);
Sass 自动解析一些 CSS 中指定的特殊常量名称为无单位数字:
pi是数学常数 π 的缩写。e是数学常数 e 的缩写。infinity、-infinity和NaN代表相应的浮点值。
@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
@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
计算函数
Sass 将以下函数解析为计算:
- 比较函数:
min()、max()和clamp() - 阶梯值函数:
round()、mod()和rem()。 - 三角函数:
sin()、cos()、tan()、asin()、acos()、atan()和atan2()。 - 指数函数:
pow()、sqrt()、hypot()、log()和exp()。 - 符号相关函数:
abs()和sign()。
遗留全局函数
CSS 在 Values and Units Level 4 中添加了对数学表达式的支持。然而,Sass 在此之前很久就支持自己的 round()、abs()、min() 和 max(),并且需要与所有这些现有样式表向后兼容。这导致需要额外的特殊语法技巧。
如果对 round()、abs()、min() 或 max() 的调用是一个有效的计算表达式,它将被解析为计算。但只要调用的任何部分包含一个计算中不支持的 SassScript 功能,例如取模运算符,它就会被解析为对相应的 Sass 数学函数的调用。
由于计算在可能的情况下无论如何都会被简化为数字,因此唯一的实质性区别是 Sass 函数只支持在构建时可以组合的单位,因此 min(12px % 10, 10%) 将抛出错误。
min()、max()、abs() 和单参数round() 是不同的:为了与允许单位/无单位混合的全局 Sass 遗留函数向后兼容(出于历史原因),只要它们直接包含在 min()、max()、abs() 或单参数 round() 计算中,这些单位就可以混合。例如,min(5 + 10px, 20px) 将得到 15px。然而 sqrt(5 + 10px) 将抛出错误,因为 sqrt(5 + 10px) 从来都不是一个全局 Sass 函数,并且这些是不兼容的单位。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);
}
$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)
.post {
padding-left: max(12px, env(safe-area-inset-left));
padding-right: max(12px, env(safe-area-inset-right));
}
.sidebar {
padding-left: 20px;
padding-right: 20px;
}
round()
round(<strategy>, number, step) 函数接受一个可选的舍入策略、一个要舍入的值和一个舍入间隔步长。strategy 应该是 nearest、up、down 或 to-zero。
$number: 12.5px;
$step: 15px;
.post-image {
// Since these round() calls are valid calculation expressions, they're
// parsed as calculations.
padding-left: round(nearest, $number, $step);
padding-right: round($number + 10px);
padding-bottom: round($number + 10px, $step + 10%);
}
$number: 12.5px
$step: 15px
.post-image
// Since these round() calls are valid calculation expressions, they're
// parsed as calculations.
padding-left: round(nearest, $number, $step)
padding-right: round($number + 10px)
padding-bottom: round($number + 10px, $step + 10%)
.post-image {
padding-left: 15px;
padding-right: 23px;
padding-bottom: round(22.5px, 15px + 10%);
}
abs()
abs() 函数对 % 单位参数的兼容性已弃用。将来,这将发出一个由浏览器解析的 CSS abs() 函数。abs(value) 接受单个表达式作为参数,并返回 $value 的绝对值。如果 $value 是负数,它返回 -$value,如果 $value 是正数,它原样返回 $value。
.post-image {
// Since these abs() calls are valid calculation expressions, they're
// parsed as calculations.
padding-left: abs(10px);
padding-right: math.abs(-7.5%);
padding-top: abs(1 + 1px);
}
.post-image
// Since these abs() calls are valid calculation expressions, they're
// parsed as calculations.
padding-left: abs(-10px)
padding-right: math.abs(-7.5%)
padding-top: abs(1 + 1px)
.post-image {
padding-left: 10px;
padding-right: 7.5%;
padding-top: 2px;
}