計算

計算式是 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()` 出現在任何其他計算中,函式呼叫將被移除,並以一般的運算取代。

程式碼遊樂場

SCSS 語法

$width: calc(400px + 10%);

.sidebar {
  width: $width;
  padding-left: calc($width / 4);
}
程式碼遊樂場

Sass 語法

$width: calc(400px + 10%)

.sidebar
  width: $width
  padding-left: calc($width / 4)

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 規範向前相容,*所有*識別符號都是允許的,預設情況下,它們會被視為未加引號的字串,並按原樣傳遞。

程式碼遊樂場

SCSS 語法

@debug calc(h + 30deg); // calc(h + 30deg);
程式碼遊樂場

Sass 語法

@debug calc(h + 30deg)  // calc(h + 30deg);

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 將以下函式解析為計算

💡 小知識

如果您定義了一個與計算函式同名的 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() 的永久連結

相容性 (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() 的永久連結

相容性 (min 和 max 語法)
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) 函數接受一個可選的捨入策略、要捨入的值和一個捨入間隔 stepstrategy 應為 nearestupdownto-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() 的永久連結

相容性 (min 和 max 語法)
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;
}