Sass 混入 @mixin:定義一次、到處 @include
混入(Mixin)把一段會重複出現的樣式包成一個名字,需要的地方用 @include 呼叫,整段就展開在那裡。它是 Sass 最常用的重用工具。
定義與呼叫
@mixin center {
display: flex;
align-items: center;
justify-content: center;
}
.modal {
@include center;
height: 100vh;
}
.avatar {
@include center;
border-radius: 50%;
}編譯後:
.modal {
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
}
.avatar {
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;
}沒有參數就不用括號
定義與呼叫都不必寫空括號。@include center; 即可。
它是複製,不是共用
上面的產出說明了混入的本質:@include 把樣式複製一份貼進去,兩個選取器各自擁有完整的宣告。
這一點常被拿來當缺點(產出會變大),但它同時也是優點:
| 特性 | 影響 |
|---|---|
| 各自獨立的宣告 | 順序可預測,不會受其他規則牽連 |
| 可以帶 參數 | 同一個混入產出不同的值 |
可以在 @media 裡使用 | @extend 做不到這件事 |
重複的字串壓縮得很好
--style=compressed 加上伺服器的 gzip,重複宣告的體積成本比想像中小很多。除非是幾十個選取器共用一大段完全相同的樣式,否則不必為此改用 @extend。
裡面可以放什麼
不只宣告,巢狀選取器、偽類、@media、甚至另一個 @include 都可以:
@mixin card-base {
padding: 16px;
border-radius: 8px;
background: #fff;
&:hover {
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
}
@media (min-width: 768px) {
padding: 24px;
}
.title {
font-weight: 700;
}
}它就是一段被命名起來的樣式區塊,展開時原樣貼上,& 也會正確接到呼叫處的選取器。
混入也能巢狀呼叫
@mixin visually-hidden {
position: absolute;
width: 1px;
height: 1px;
overflow: hidden;
clip-path: inset(50%);
}
@mixin sr-only-focusable {
@include visually-hidden;
&:focus {
position: static;
width: auto;
height: auto;
clip-path: none;
}
}跨檔案使用
// abstracts/_mixins.scss
@mixin center { /* ... */ }// components/_card.scss
@use "../abstracts/mixins" as mx;
.card {
@include mx.center;
}命名慣例
| 慣例 | 範例 |
|---|---|
| 用動詞或效果命名 | center、truncate、visually-hidden |
| 帶參數的說明用途 | respond-to($bp)、text-style($size) |
| 元件專用的加前綴 | btn-base、card-shadow |
| 內部使用的加底線 | _reset-list,見 私有成員 |
該放哪個檔案
abstracts/
└── _mixins.scss ← 全專案共用,且不產生任何 CSS
components/
└── _button.scss ← 只有按鈕會用到的混入就放這裡abstracts 裡的檔案不該有 CSS 規則
_mixins.scss 裡若寫了選取器,每個載入它的檔案都會多輸出一份樣式。那裡只放 定義,見 abstracts 該放什麼。
常見的實用混入
// 單行文字截斷
@mixin truncate {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
// 清除浮動
@mixin clearfix {
&::after {
content: "";
display: block;
clear: both;
}
}
// 固定比例的容器
@mixin ratio($w, $h) {
aspect-ratio: #{$w} / #{$h};
}參數的完整用法見 混入的參數,把整段樣式傳進混入的做法見 @content。
常見問題
混入會讓產出的 CSS 變大嗎?
會。@include 是把整段樣式複製一份貼進去,呼叫十次就出現十份宣告。不過壓縮與 gzip 對這種重複字串的效果很好,實務上多半不是問題,真正需要合併選取器時才考慮 @extend。
混入裡面可以放選取器嗎?
可以。混入的內容不限於宣告,巢狀選取器、偽類、媒體查詢、甚至另一個 @include 都能放。它就是一段被命名起來的樣式區塊,展開時原樣貼上。
沒有參數的混入呼叫時要加括號嗎?
不用。寫成 @include center; 就好,加上空括號寫成 @include center(); 也合法但多餘。定義時同理,沒有參數就不必寫括號。
混入該放在哪個檔案?
全專案共用的放在 abstracts 目錄的 _mixins.scss;只有單一元件會用到的就放在該元件自己的檔案裡。放進 abstracts 的混入不該產生任何 CSS,這樣被載入幾次都不會多輸出樣式。