計算
計算式是 Sass 表示 calc()
函式的方式,以及類似的函式,例如 clamp()
、min()
和 max()
。 Sass 會盡可能簡化這些計算式,即使它們彼此組合在一起也是如此。
- Dart Sass
- 自 1.40.0 起
- LibSass
- ✗
- Ruby Sass
- ✗
LibSass、Ruby Sass 和 1.40.0 之前的 Dart Sass 版本會將 calc()
解析為類似 element()
的特殊函式。
LibSass、Ruby Sass 和 1.31.0 之前的 Dart Sass 版本會將 clamp()
解析為一般的 CSS 函式,而不是在其內支援特殊語法。1.31.0 到 1.40.0 之間的 Dart Sass 版本會將 clamp()
解析為類似 element()
的特殊函式。
- Dart Sass
- 自 1.67.0 起
- LibSass
- ✗
- Ruby Sass
- ✗
1.40.0 到 1.67.0 之間的 Dart Sass 版本不允許在計算中使用多個未以運算子分隔的值,即使在 calc(1 var(--plus-two))
等有效 CSS 的情況下也是如此(因為 --plus-two
可以定義為 + 2
)。
從 Dart Sass 1.67.0 開始,計算中的多個值可以用空格分隔,只要每個其他值都評估為未加引號的字串(例如 var()
表達式或未加引號的字串 "+ 2"
)。
SCSS 語法
@debug calc(400px + 10%); // calc(400px + 10%)
@debug calc(400px / 2); // 200px
@debug min(100px, calc(1rem + 10%)); // min(100px, 1rem + 10%)
Sass 語法
@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 語法,而不是特殊的計算語法!
您也可以在計算中使用插值。但是,如果您這樣做,任何涉及該插值的運算都不會被簡化或進行類型檢查,因此很容易產生額外冗長甚至無效的 CSS。与其撰寫 `calc(10px + #{$var})`,不如直接撰寫 `calc(10px + $var)`!
簡化簡化永久連結
如果計算中相鄰的運算使用可以在編譯時期組合的單位,例如 `1in + 10px` 或 `5s * 2`,Sass 會簡化這些運算。如果可能,它甚至會將整個計算簡化為單一數字——例如,`clamp(0px, 30px, 20px)` 將返回 `20px`。
⚠️ 注意!
這表示計算表達式不一定總是返回計算結果!如果您正在撰寫 Sass 函式庫,您可以隨時使用`meta.type-of()` 函式來判斷您正在處理的類型。
計算也會在其他計算中被簡化。特別是,如果 `calc()` 出現在任何其他計算中,函式呼叫將被移除,並以一般的運算取代。
CSS 輸出
.sidebar {
width: calc(400px + 10%);
padding-left: calc((400px + 10%) / 4);
}
運算運算永久連結
您不能將計算與一般的 SassScript 運算(例如 `+` 和 `*`)一起使用。如果您想撰寫一些允許計算的數學函式,只需將它們寫在自己的 `calc()` 表達式中即可——如果它們傳入了一堆具有相容單位的數字,它們也會返回一般數字,如果它們傳入了計算,它們也會返回計算結果。
之所以有此限制,是為了確保如果*不*需要計算,它們會盡快拋出錯誤。計算不能用於所有一般數字可以使用的場合:例如,它們不能注入到 CSS 識別符號中(例如 `.item-#{$n}`),也不能傳遞給 Sass 的內建數學函式。將 SassScript 運算保留給一般數字,可以清楚地表明計算允許使用的位置以及不允許使用的位置。
SCSS 語法
$width: calc(100% + 10px);
@debug $width * 2; // Error!
@debug calc($width * 2); // calc((100% + 10px) * 2);
Sass 語法
$width: calc(100% + 10px);
@debug $width * 2; // Error!
@debug calc($width * 2); // calc((100% + 10px) * 2);
常數常數永久連結
- Dart Sass
- 自 1.60.0 版本起
- LibSass
- ✗
- Ruby Sass
- ✗
計算也可以包含常數,它們以 CSS 識別符號的形式撰寫。為了與未來的 CSS 規範向前相容,*所有*識別符號都是允許的,預設情況下,它們會被視為未加引號的字串,並按原樣傳遞。
Sass 會自動解析一些在 CSS 中指定的特殊常數名稱為無單位數字。
-
`pi` 是數學常數 *π* 的簡寫。
-
`e` 是數學常數 *e* 的簡寫。
-
`infinity`、`-infinity` 和 `NaN` 表示對應的浮點值。
SCSS 語法
@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 語法
@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
計算函式計算函式永久連結
- Dart Sass
- 自 1.65.0 版本起
- LibSass
- ✗
- Ruby Sass
- ✗
Dart Sass 1.65.0 及之後版本 *除了* 1.66.x 系列以外,皆能處理以下這些計算函式的執行:round()
、mod()
、rem()
、sin()
、cos()
、tan()
、asin()
、acos()
、atan()
、atan2()
、pow()
、sqrt()
、hypot()
、log()
、exp()
、abs()
以及 sign()
。
在 Dart Sass 1.65.x 版本中,任何名稱與計算函式相符的函式呼叫 *總是* 會被解析為計算函式。這破壞了一些現有的使用者自訂函式,因此在新計算函式的支援在 1.66.0 中被移除,直到 1.67.0 版本中能 *在不* 破壞現有行為的情況下重新加入。
Sass 將以下函式解析為計算
- 比較函式:
min()
、max()
以及clamp()
- 步進值函式:
round()
、mod()
以及rem()
。 - 三角函式:
sin()
、cos()
、tan()
、asin()
、acos()
、atan()
以及atan2()
。 - 指數函式:
pow()
、sqrt()
、hypot()
、log()
以及exp()
。 - 正負號相關函式:
abs()
和sign()
。
💡 小知識
如果您定義了一個與計算函式同名的 Sass 函式,Sass 將會永遠呼叫您的函式,而不是建立計算值。
舊版全域函式舊版全域函式永久連結
CSS 在「值與單位等級 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()
min() 和 max() 的永久連結
- Dart Sass
- 自 >=1.11.0 <1.42.0 起
- LibSass
- ✗
- Ruby Sass
- ✗
LibSass、Ruby Sass 和 1.11.0 之前的 Dart Sass 版本*總是*將 min()
和 max()
解析為 Sass 函數。要為這些實作建立純 CSS min()
或 max()
呼叫,您可以改寫 unquote("min(#{$padding}, env(safe-area-inset-left))")
之類的程式碼。
CSS 在「值與單位等級 4」中新增了對 min()
和 max()
函數 的支援,Safari 也很快採用了它們 以支援 iPhoneX。由於我們已經支援 min()
和 max()
作為傳統 Sass 函數,因此我們必須實作向後相容的邏輯以及作為 CSS 函數的支援。
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()
函數向後不相容,因此該行為已恢復。
SCSS 語法
$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);
}
Sass 語法
$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)
CSS 輸出
.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() 的永久連結
- Dart Sass
- 自 1.65.0 版本起
- LibSass
- ✗
- Ruby Sass
- ✗
LibSass、Ruby Sass 和 1.65.0 之前的 Dart Sass 版本,以及 Dart Sass 1.66.x,*總是*將 round()
解析為 Sass 函數。要在這些實作中使用純 CSS 函數,您可以改寫 round(#{$strategy, $number, $step})
之類的程式碼。
round(<strategy>, number, step)
函數接受一個可選的捨入策略、要捨入的值和一個捨入間隔 step
。strategy
應為 nearest
、up
、down
或 to-zero
。
SCSS 語法
$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%);
}
Sass 語法
$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%)
CSS 輸出
.post-image {
padding-left: 15px;
padding-right: 23px;
padding-bottom: round(22.5px, 15px + 10%);
}
abs()
abs() 的永久連結
- Dart Sass
- 自 1.67.0 起
- LibSass
- ✗
- Ruby Sass
- ✗
LibSass、Ruby Sass 和 1.67.0 之前的 Dart Sass 版本*總是*將 abs()
解析為 Sass 函數。要為這些實作建立純 CSS 計算,您可以改寫 abs(#{$number})
之類的程式碼。
⚠️ 注意!
全局 abs()
函數與百分比單位參數的相容性已被棄用。未來,這將發出 CSS abs() 函數,由瀏覽器解析。
abs(value)
接受單個表達式作為參數,並返回 $value
的絕對值。如果 $value
為負數,則返回 -$value
,如果 $value
為正數,則按原樣返回 $value
。
SCSS 語法
.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);
}
Sass 語法
.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)
CSS 輸出
.post-image {
padding-left: 10px;
padding-right: 7.5%;
padding-top: 2px;
}