Sass 對照表 map:主題、斷點與刻度的資料結構
map 是鍵值對的集合,Sass 裡最重要的資料結構。主題色、斷點、間距刻度、字級表,這些「一組有名字的設定」都該收進 map,而不是散落成十幾個 變數。
建立
$theme: (
primary: #2965f1,
danger: #e03131,
success: #2f9e44,
);
$breakpoints: (
sm: 576px,
md: 768px,
lg: 992px,
);最後一項後面留逗號
success: #2f9e44, 結尾的逗號是合法的,之後新增一行時 diff 只會有一行變動。
取值
@use "sass:map";
.btn {
background: map.get($theme, primary);
}取不到時回傳 null:
color: map.get($theme, primry); // 打錯字 → null → 這一行整個不輸出這是 map 最危險的地方
沒有錯誤、沒有警告,樣式就是不見了。建議一律包一層取值函式:
@use "sass:map";
@function color-of($name) {
@if not map.has-key($theme, $name) {
@error "色彩 #{$name} 不存在,可用的有:#{map.keys($theme)}。";
}
@return map.get($theme, $name);
}常用操作
@use "sass:map";
map.get($theme, primary) // 取值
map.has-key($theme, primary) // 有沒有這個鍵 → true / false
map.keys($theme) // 所有鍵 → primary, danger, success
map.values($theme) // 所有值
map.set($theme, info, #1c7ed6) // 回傳「加了一項」的新 map
map.merge($a, $b) // 回傳合併後的新 map
map.remove($theme, danger) // 回傳「移除一項」的新 mapmap 是不可變的
map.set() 與 map.merge() 都不會改到原本的 map,它們回傳新的。要留下結果得指派回去:
$theme: map.set($theme, info, #1c7ed6);完整函式表見 sass:map。
搭配迴圈:map 真正的價值
一張表加一個 @each,換來一整批樣式:
@each $name, $color in $theme {
.text-#{$name} { color: $color; }
.bg-#{$name} { background: $color; }
}之後設計師要加一個 warning,你只要在 map 加一行,所有相關的類別自動生出來。這就是「資料與樣式分離」。
巢狀 map
一個項目要記好幾個屬性時:
$buttons: (
primary: (bg: #2965f1, text: #fff, border: transparent),
ghost: (bg: transparent, text: #2965f1, border: currentColor),
);
@each $name, $conf in $buttons {
.btn-#{$name} {
background: map.get($conf, bg);
color: map.get($conf, text);
border: 1px solid map.get($conf, border);
}
}map.get() 也可以一次鑽好幾層:
map.get($buttons, primary, bg) // #2965f1合併巢狀 map 要用 deep-merge
$base: (btn: (bg: #2965f1, radius: 4px));
$over: (btn: (bg: #e03131));
map.merge($base, $over);
// → (btn: (bg: #e03131)) ← radius 不見了!
map.deep-merge($base, $over);
// → (btn: (bg: #e03131, radius: 4px)) ✅map.merge() 只看第一層,第二層是整個換掉。做主題覆寫時幾乎都該用 deep-merge。
鍵的型別
任何型別都能當鍵,但實務上一律用 不帶引號的識別字:
$a: (primary: red);
map.get($a, primary); // ✅ red
map.get($a, "primary"); // ❌ null:帶引號是不同的鍵不帶引號的 primary 與帶引號的 "primary" 在 Sass 裡是兩個不同的鍵,混用就取不到值。細節見 資料型別。
一個完整的設定檔
// abstracts/_tokens.scss
$breakpoints: (sm: 576px, md: 768px, lg: 992px) !default;
$spacing: (0: 0, 1: 4px, 2: 8px, 3: 16px, 4: 24px, 5: 32px) !default;
$colors: (
primary: #2965f1,
danger: #e03131,
text: #333333,
surface: #ffffff,
) !default;加上 !default 就能讓使用這個模組的人用 @use ... with 覆寫。這是 abstracts 目錄 的標準寫法。
常見問題
map 的鍵取不到值時會怎樣?
回傳 null,不會報錯。而值為 null 的宣告整行都不會輸出,所以打錯鍵名的結果就是那條樣式安靜地消失。建議包一層取值函式,取不到就用 @error 明確報錯。
map 可以修改嗎?
map 本身不可變更,map.set() 與 map.merge() 都是回傳一個新的 map,原本那個不受影響。要留下結果就得把回傳值指派回變數。
巢狀 map 怎麼取值?
map.get() 可以接多個鍵,依序往下鑽。合併巢狀 map 時要用 map.deep-merge(),一般的 map.merge() 只會整個換掉第二層,不會逐層合併。
map 的鍵要用什麼型別?
任何型別都可以,但實務上一律用不帶引號的識別字,例如 primary、md。要注意帶引號與不帶引號的字串是不同的鍵,混用會取不到值。