Sass sass:string:引號、擷取與字串處理
CSS 裡有兩種字串:content: "文字" 需要引號,font-family: sans-serif 不能有引號。sass:string 管的主要就是這件事,順帶提供擷取與搜尋。
scss
@use "sass:string";引號的處理
scss
string.quote(sans-serif) // "sans-serif"
string.unquote("sans-serif") // sans-serif典型情境是從 map 取出的關鍵字被存成帶引號的字串:
scss
$config: (display: "flex");
.a { display: map.get($config, display); } // display: "flex"; ❌
.b { display: string.unquote(map.get($config, display)); } // display: flex; ✅插值本來就會去掉引號
#{map.get($config, display)} 也能達到同樣效果。單純要去引號時用 插值 就好,unquote() 適合用在函式內部需要回傳無引號值的時候。
反過來,content 需要引號:
scss
.crumb::after {
content: string.quote($name); // 不論原本有沒有引號都補上
}擷取與長度
scss
string.length("primary") // 7
string.slice("primary", 1, 3) // "pri"
string.slice("btn-primary", 5) // "primary",只給起點就取到底
string.slice("primary", -3) // "ary",負數從尾端算索引從 1 開始,不是 0
string.slice($s, 1, 3) 取的是第一到第三個字元。list 也是同樣的規則。
一個實用例子,去掉開頭的 #:
scss
@function strip-hash($hex) {
@if string.slice($hex, 1, 1) == "#" {
@return string.slice($hex, 2);
}
@return $hex;
}搜尋
scss
string.index("btn-primary", "-") // 4
string.index("btn-primary", "xyz") // null,找不到搭配 slice() 就能做簡單的切割:
scss
@function before-dash($s) {
$i: string.index($s, "-");
@return if($i, string.slice($s, 1, $i - 1), $s);
}
before-dash("btn-primary") // "btn"插入
scss
string.insert("btnprimary", "-", 4) // "btn-primary"
string.insert("primary", "btn-", 1) // "btn-primary"大小寫
scss
string.to-upper-case("primary") // "PRIMARY"
string.to-lower-case("PRIMARY") // "primary"unique-id:產生唯一名稱
scss
$name: string.unique-id(); // 例如 u2f8b31c9
@keyframes #{$name} {
from { opacity: 0; }
to { opacity: 1; }
}@keyframes 與 counter 的名稱是全域的,元件庫裡用它避免撞名。
每次編譯結果都不同
產出的 CSS 會因此每次都不一樣,不利於快取比對與 diff 檢視。除非真的需要,否則手動加專案前綴更好。
沒有 replace 函式
Sass 沒有內建的字串取代,需要的話自己寫:
scss
@use "sass:string";
@function str-replace($s, $search, $replace: "") {
$i: string.index($s, $search);
@if $i {
@return string.slice($s, 1, $i - 1)
+ $replace
+ str-replace(
string.slice($s, $i + string.length($search)),
$search,
$replace
);
}
@return $s;
}這是遞迴的寫法,處理 SVG data URI 的字元轉義時常用到。
什麼時候不必用這個模組
單純串接字串用 插值 就好:
scss
$prefix: "btn";
$name: "primary";
.#{$prefix}-#{$name} { } // ✅ 清楚sass:string 留給真正需要擷取、搜尋、替換的場合。
常見問題
什麼時候需要 unquote?
當一個值被存成帶引號的字串,但輸出時不能有引號的時候,例如從 map 取出的 CSS 關鍵字。不過多數情況用插值就會自動去掉引號,不必特地呼叫這個函式。
字串的索引從 0 還是 1 開始?
從 1 開始,這與大多數程式語言不同。負數則代表從尾端往回數,-1 是最後一個字元,擷取整段時很方便。
string.length 算的是字元還是位元組?
算的是字元數,所以一個中文字算一個。要注意它算的是不含引號的內容長度。
串接字串該用插值還是這個模組?
單純串接用插值就好,意圖清楚也不必記引號規則。需要擷取、搜尋、替換這類真正的字串處理時才用 sass:string。