Sass 插值 #{}:把值放進選取器、屬性名與字串
變數 有個硬性限制:只能出現在屬性值的位置。想把它放進選取器、屬性名稱或媒體查詢的條件裡,就得用 插值(Interpolation)#{} 把它包起來。
插值做的事很單純:把大括號裡的運算結果算完,換成純文字塞進去。
一、選取器
$block: "card";
.#{$block} {
padding: 16px;
}
.#{$block}__title {
font-size: 20px;
}.card { padding: 16px; }
.card__title { font-size: 20px; }搭配 @each 就能批次產生一整組類別:
@each $name, $color in (primary: #2965f1, danger: #e03131) {
.text-#{$name} {
color: $color;
}
}.text-primary { color: #2965f1; }
.text-danger { color: #e03131; }二、屬性名稱
$side: left;
.box {
margin-#{$side}: 16px;
padding-#{$side}: 8px;
}.box {
margin-left: 16px;
padding-left: 8px;
}前綴也可以插值,#{$prefix}-transform: none; 這種寫法在處理舊版瀏覽器前綴時很常見。
三、媒體查詢的條件
@media 的括號裡不是屬性值,變數要插值才會生效:
$bp-md: 768px;
@media (min-width: #{$bp-md}) {
.card { padding: 32px; }
}四、寫進 CSS 自訂屬性
自訂屬性的值對 Sass 來說是「原樣輸出」的內容,不會做替換:
$brand: #2965f1;
:root {
--brand-wrong: $brand; // 輸出字面上的 $brand,無效
--brand: #{$brand}; // 輸出 #2965f1 ✅
}:root {
--brand-wrong: $brand;
--brand: #2965f1;
}這是 Sass 與原生 CSS 變數搭配時最常踩的坑,完整做法見 搭配 CSS 自訂屬性。
五、字串與 URL
$path: "/images/sass";
.hero {
background-image: url("#{$path}/banner.svg");
}$name: "首頁";
.crumb::after {
content: "#{$name}"; // 引號要自己補
}插值會拿掉引號
#{$name} 輸出的是不帶引號的 首頁。content 屬性需要引號,所以要在插值外面自己加,或改用 string.quote(),見 sass:string。
六、@keyframes 的名稱
$name: "fade";
@keyframes #{$name}-in {
from { opacity: 0; }
to { opacity: 1; }
}
.modal {
animation: #{$name}-in 0.3s;
}什麼時候不要用插值
一、屬性值的位置。 直接寫變數就好:
.btn {
color: #{$brand}; // ❌ 多此一舉,還會轉成字串
color: $brand; // ✅
}多包一層插值會讓值失去型別,之後就不能拿它做 運算 或傳給需要色彩型別的函式。
二、數字運算。 插值裡做完運算會變成不帶單位的字串:
$w: 100px;
.a { width: #{$w / 2}; } // ❌ 得到無法再運算的字串
.b { width: math.div($w, 2); } // ✅ 仍是 50px 這個數值常見問題
什麼時候需要用插值?
變數出現在屬性值以外的位置時都需要,包括選取器、屬性名稱、媒體查詢的條件、@keyframes 的名稱,以及要寫進 CSS 自訂屬性的值。單純當作屬性值使用時直接寫變數名即可,不必插值。
為什麼 CSS 自訂屬性裡的 Sass 變數沒有被替換?
因為自訂屬性的值被 Sass 視為原樣輸出的內容,不會做運算或替換。要把 Sass 變數的值寫進去必須用插值,寫成 --brand: #{$brand}。
插值會影響輸出的引號嗎?
會。插值輸出字串時會去掉引號,所以 content 屬性用插值時要自己補上引號,或改用 string.quote() 處理,否則產出的 CSS 會是無效的。
屬性值可以直接用插值嗎?
可以但不建議。屬性值的位置直接寫變數就好,多包一層插值會把值轉成字串,失去型別資訊,之後就沒辦法拿它做運算或傳給需要特定型別的函式。