Sass 走訪迴圈 @each:批次產生類別
@each 走訪一組資料,每一項執行一次區塊內容。它是 Sass 裡最常用的迴圈,主題色、間距刻度、斷點、圖示,這些「一組資料對應一組樣式」的需求都靠它。
走訪 list
scss
$sides: top, right, bottom, left;
@each $side in $sides {
.m-#{$side} {
margin-#{$side}: 16px;
}
}css
.m-top { margin-top: 16px; }
.m-right { margin-right: 16px; }
.m-bottom { margin-bottom: 16px; }
.m-left { margin-left: 16px; }變數要放進選取器與屬性名,必須用 插值。
走訪 map
寫兩個變數就能同時拿到鍵與值:
scss
$theme: (
primary: #2965f1,
danger: #e03131,
success: #2f9e44,
);
@each $name, $color in $theme {
.text-#{$name} { color: $color; }
.bg-#{$name} { background: $color; }
}css
.text-primary { color: #2965f1; }
.bg-primary { background: #2965f1; }
.text-danger { color: #e03131; }
.bg-danger { background: #e03131; }
.text-success { color: #2f9e44; }
.bg-success { background: #2f9e44; }一組資料換來六條規則,之後新增一個顏色只要在 map 加一行。
解構多個值
list 裡放 list 的話,可以一次取出多個欄位:
scss
$buttons: (
(primary, #2965f1, #fff),
(danger, #e03131, #fff),
(warning, #f59f00, #1a1a1a),
);
@each $name, $bg, $fg in $buttons {
.btn-#{$name} {
background: $bg;
color: $fg;
}
}欄位一多就改用 map
三欄以上時,(name: primary, bg: #2965f1, fg: #fff) 這種 map 比位置對應好讀,也不怕漏一欄就整組錯位。取值用 map.get()。
巢狀走訪
主題乘上狀態,交叉產生:
scss
@use "sass:map";
$themes: (
light: (bg: #fff, text: #333),
dark: (bg: #1a1a1a, text: #f5f5f5),
);
@each $name, $tokens in $themes {
[data-theme="#{$name}"] {
@each $key, $value in $tokens {
--#{$key}: #{$value};
}
}
}css
[data-theme="light"] { --bg: #fff; --text: #333; }
[data-theme="dark"] { --bg: #1a1a1a; --text: #f5f5f5; }搭配混入
迴圈裡呼叫 混入 也很常見:
scss
@each $bp in (sm, md, lg) {
@include respond-to($bp) {
.container-#{$bp} { max-width: 100%; }
}
}小心組合爆炸
scss
// ⚠️ 4 個屬性 × 4 個方向 × 10 個尺寸 = 160 條規則
@each $prop in (margin, padding) {
@each $side in (top, right, bottom, left) {
@each $i in (1, 2, 3, 4, 5, 6, 7, 8, 9, 10) {
.#{$prop}-#{$side}-#{$i} { #{$prop}-#{$side}: $i * 4px; }
}
}
}三層巢狀迴圈很容易產出上千條你永遠用不到的規則。
常見問題
@each 可以同時取出鍵和值嗎?
可以。走訪 map 時寫兩個變數,第一個接鍵、第二個接值。走訪由多個 list 組成的 list 時也能用同樣的方式一次解構出多個欄位。
迴圈裡怎麼把變數變成類別名稱?
用 插值。變數不能直接出現在選取器的位置,要寫成 .text-#{$name} 這種形式,編譯時就會展開成一條條實際的類別。
產生太多類別會不會讓 CSS 變肥?
會,而且很容易失控。三個維度各十個值交叉相乘就是一千條規則。只產生專案真的會用到的組合,或改用能自動移除未使用樣式的工具。
@each 和 @for 該用哪個?
有一組現成的資料要逐項處理就用 @each;需要的是一連串連續的數字,例如柵格的一到十二欄,就用 @for。多數情況 @each 的可讀性比較好。