Sass 內建模組總覽:七個 sass: 前綴的工具箱
Dart Sass 把所有內建函式整理成 七個模組,用 @use 載入後以命名空間呼叫:
@use "sass:math";
@use "sass:color";
.card {
width: math.div(100%, 3);
border-color: color.scale(#2965f1, $lightness: -20%);
}七個模組
| 模組 | 職責 | 代表函式 |
|---|---|---|
sass:math | 數字運算 | div()、round()、percentage() |
sass:color | 色彩調整 | scale()、adjust()、mix() |
sass:string | 字串處理 | unquote()、slice()、index() |
sass:list | 清單操作 | nth()、append()、join() |
sass:map | 對照表操作 | get()、merge()、has-key() |
sass:meta | 反射與檢查 | type-of()、inspect()、load-css() |
sass:selector | 選取器操作 | nest()、append()、unify() |
為什麼要改成模組
早期所有函式都在全域,可以直接寫 lighten($c, 10%)。問題有兩個:
一、容易撞名。 自訂一個 round() 就蓋掉內建的;CSS 未來新增同名函式也會衝突。
二、看不出來源。 一份專案裡的 tint() 到底是內建的、第三方套件的、還是同事寫的?
改成模組之後,math.round() 與 round() 一眼分得出來,也不再互相干擾。
全域函式已被棄用
lighten()、darken()、percentage() 這些全域寫法還能編譯,但會出現棄用警告,未來會移除。新程式碼一律用模組寫法。
對照表:舊寫法換新寫法
| 舊的全域函式 | 現在的寫法 |
|---|---|
percentage($x) | math.percentage($x) |
round($x) | math.round($x) |
$a / $b | math.div($a, $b) |
lighten($c, 10%) | color.scale($c, $lightness: 10%) |
darken($c, 10%) | color.scale($c, $lightness: -10%) |
map-get($m, $k) | map.get($m, $k) |
nth($l, 1) | list.nth($l, 1) |
type-of($x) | meta.type-of($x) |
str-slice($s, 1, 3) | string.slice($s, 1, 3) |
lighten 不只是改名
color.scale() 的行為與 lighten() 不同,它是按比例縮放而不是加減固定值,結果通常更自然。轉換時要重新確認顏色,見 sass:color。
載入的三件事
一、每個檔案都要自己載入。
// _a.scss
@use "sass:math"; // 這裡載入了
// _b.scss
// 沒寫 → 這裡的 math.div() 會報錯二、載入不會產生任何 CSS。 內建模組只有函式,沒有規則,載入十個也不會讓產出變大。
三、可以改命名空間。
@use "sass:math" as m;
.a { width: m.div(100%, 3); }特例:不需要載入的函式
if():全域可用,見 條件判斷。rgb()、hsl()、url()、calc():這些是 CSS 的 函式,Sass 會原樣輸出交給瀏覽器。
calc() 裡的 Sass 變數要插值
width: calc(100% - $gap) 不會生效,要寫成 calc(100% - #{$gap}),見 插值。
該把載入寫在哪
慣例是放在每個檔案最上方,緊接著自家模組之前:
@use "sass:math";
@use "sass:map";
@use "../abstracts" as a;
.card {
padding: a.space(2);
width: math.div(100%, 3);
}@use 必須排在所有 CSS 規則之前,規則見 @use。
常見問題
為什麼舊的全域函式被棄用?
早期所有內建函式都在全域,名稱像 lighten、round 這種很容易與自訂函式或未來的 CSS 函式撞名。改成模組加命名空間之後,來源一目了然,也不再有衝突。
每個檔案都要重新載入內建模組嗎?
要。模組系統沒有「全域可用」這回事,A 檔案載入了 sass:math 不代表 B 檔案也拿得到,用到的檔案都要自己在最上方寫一次。
載入內建模組會增加產出的 CSS 嗎?
不會。內建模組只提供函式,本身不含任何 CSS 規則,載入多少個都不會讓輸出變大,也不會影響編譯速度。
哪些函式不需要載入模組?
if() 是特例,它是全域可用的。另外 rgb()、hsl()、url() 這些是 CSS 本身的函式,會原樣輸出交給瀏覽器,不屬於 Sass 的內建模組。