Sass sass:list:清單的取值、附加與合併
list 是有順序的一串值。CSS 裡到處都是它:margin: 8px 16px、font-family: A, B, C、transition: color 0.2s, background 0.3s 全都是 list。
@use "sass:list";建立
用逗號或空白分隔,括號可省略:
$font: "Noto Sans TC", sans-serif; // 逗號分隔
$border: 1px solid #ddd; // 空白分隔
$sizes: (8px, 16px, 24px);
$empty: ();分隔符會被記住,輸出時原樣使用。所以要拿來當 font-family 就用逗號、當 margin 就用空白。
取值
$sizes: (8px, 16px, 24px);
list.nth($sizes, 1) // 8px
list.nth($sizes, -1) // 24px,負數從尾端算
list.length($sizes) // 3
list.index($sizes, 16px) // 2,找不到回傳 null索引從 1 開始
list.nth($sizes, 0) 會直接報錯。這與 CSS 的 :nth-child() 一致,但與多數程式語言相反。
附加與合併
$a: (8px, 16px);
list.append($a, 24px) // (8px, 16px, 24px)
list.join($a, (24px, 32px)) // (8px, 16px, 24px, 32px)差別在於「加入的東西是不是清單」:
list.append($a, (24px, 32px)) // (8px, 16px, (24px, 32px)) ← 巢狀
list.join($a, (24px, 32px)) // (8px, 16px, 24px, 32px) ← 攤平list 不可變更
兩個函式都是 回傳新的 list,原本的不會變:
list.append($a, 24px); // ❌ 結果被丟掉
$a: list.append($a, 24px); // ✅控制分隔符
list.append($a, 24px, $separator: comma)
list.join($a, $b, $separator: space)
list.separator($a) // comma 或 space組 box-shadow 時特別重要,各組陰影之間要逗號,組內要空白:
@use "sass:list";
$shadows: ();
@each $i in (1, 2, 3) {
$shadows: list.append($shadows, 0 ($i * 2px) ($i * 4px) #0002, comma);
}
.card { box-shadow: $shadows; }zip:配對
list.zip((a, b, c), (1, 2, 3)) // ((a 1), (b 2), (c 3))搭配 @each 的解構:
$names: (sm, md, lg);
$sizes: (576px, 768px, 992px);
@each $name, $size in list.zip($names, $sizes) {
.container-#{$name} { max-width: $size; }
}這種需求其實用 map 更好
(sm: 576px, md: 768px) 一眼看得出對應關係,不必擔心兩個 list 長度不一致。見 對照表 map。
其他
list.set-nth($a, 2, 20px) // 回傳「第 2 項換成 20px」的新 list
list.is-bracketed([1, 2]) // true,方括號的 list
list.slash(1, 2, 3) // 產生 1 / 2 / 3 這種斜線分隔的值list.slash() 是給 grid-area、font 簡寫這類需要斜線的地方用的,因為斜線已經不是 除法 了。
單一值也是 list
list.length(16px) // 1
list.nth(16px, 1) // 16px
@each $x in 16px { } // 跑一輪Sass 把任何值都當成長度為 1 的 list。寫通用函式時很方便:
@mixin sides($values) {
@if list.length($values) == 1 {
padding: $values;
} @else {
padding: list.nth($values, 1) list.nth($values, 2);
}
}常見問題
list 的索引為什麼從 1 開始?
這是 Sass 的設計,與 CSS 的 :nth-child() 從 1 起算一致。從其他程式語言過來的人很容易寫成 0,那會直接得到錯誤。
append 和 join 差在哪?
append 是把一個值加到清單尾端,join 是把兩個清單接成一個。要加入的東西本身是清單時,用 append 會變成巢狀清單,用 join 才會攤平成同一層。
清單可以就地修改嗎?
不行,所有函式都是回傳新的清單,原本那個不會變。要留下結果就得把回傳值指派回變數,這一點與 map 相同。
單一個值算不算清單?
算,Sass 把任何值都視為長度為一的清單。所以對一個色碼呼叫長度函式會得到 1,走訪它也會跑一輪,寫通用函式時可以省下型別判斷。