@mixin 與 @include
Mixin 允許您定義可在整個樣式表中重複使用的樣式。它們讓您可以輕鬆避免使用非語意類別,例如 .float-left
,並在程式庫中分發樣式集合。
Mixin 是使用 @mixin
at-rule 定義的,其寫法為 @mixin <名稱> { ... }
或 @mixin 名稱(<參數...>) { ... }
。Mixin 的名稱可以是任何不以 --
開頭的 Sass 識別符號,並且可以包含任何陳述式,除了頂層陳述式之外。它們可以用於封裝可放入單個樣式規則的樣式;它們可以包含自己的樣式規則,這些規則可以嵌套在其他規則中或包含在樣式表的頂層;或者它們也可以僅用於修改變數。
Mixin 使用 @include
at-rule 包含到目前的上下文中,其寫法為 @include <名稱>
或 @include <名稱>(<參數...>)
,其中包含要包含的 Mixin 的名稱。
SCSS 語法
@mixin reset-list {
margin: 0;
padding: 0;
list-style: none;
}
@mixin horizontal-list {
@include reset-list;
li {
display: inline-block;
margin: {
left: -2px;
right: 2em;
}
}
}
nav ul {
@include horizontal-list;
}
Sass 語法
@mixin reset-list
margin: 0
padding: 0
list-style: none
@mixin horizontal-list
@include reset-list
li
display: inline-block
margin:
left: -2px
right: 2em
nav ul
@include horizontal-list
CSS 輸出
nav ul {
margin: 0;
padding: 0;
list-style: none;
}
nav ul li {
display: inline-block;
margin-left: -2px;
margin-right: 2em;
}
💡 小知識
Mixin 名稱,如同所有 Sass 的識別符號,視連字號和底線為相同。這表示 reset-list
和 reset_list
都指向同一個 mixin。這是 Sass 早期遺留下來的設計,當時它只允許在識別符號名稱中使用底線。當 Sass 加入支援連字號以符合 CSS 的語法後,為了讓遷移更容易,兩者被設為等效。
參數參數永久連結
Mixin 也可以接受參數,這允許每次呼叫它們時自訂其行為。參數在 @mixin
規則中,mixin 名稱之後,以括號括住的變數名稱列表指定。然後,mixin 必須以相同數量的參數,以SassScript 表達式的形式引入。這些表達式的值在 mixin 的主體中作為對應的變數提供。
SCSS 語法
@mixin rtl($property, $ltr-value, $rtl-value) {
#{$property}: $ltr-value;
[dir=rtl] & {
#{$property}: $rtl-value;
}
}
.sidebar {
@include rtl(float, left, right);
}
Sass 語法
@mixin rtl($property, $ltr-value, $rtl-value)
#{$property}: $ltr-value
[dir=rtl] &
#{$property}: $rtl-value
.sidebar
@include rtl(float, left, right)
CSS 輸出
.sidebar {
float: left;
}
[dir=rtl] .sidebar {
float: right;
}
💡 小知識
參數列表也可以有尾隨逗號!這可以更容易避免在重構樣式表時出現語法錯誤。
選用參數選用參數永久連結
通常,mixin 宣告的每個參數都必須在引入該 mixin 時傳遞。但是,您可以透過定義一個預設值來讓參數變成選用的,如果未傳遞該參數,則會使用該預設值。預設值使用與變數宣告相同的語法:變數名稱,後跟冒號和SassScript 表達式。這使得定義彈性的 mixin API 變得容易,可以用於簡單或複雜的方式。
SCSS 語法
@mixin replace-text($image, $x: 50%, $y: 50%) {
text-indent: -99999em;
overflow: hidden;
text-align: left;
background: {
image: $image;
repeat: no-repeat;
position: $x $y;
}
}
.mail-icon {
@include replace-text(url("/images/mail.svg"), 0);
}
Sass 語法
@mixin replace-text($image, $x: 50%, $y: 50%)
text-indent: -99999em
overflow: hidden
text-align: left
background:
image: $image
repeat: no-repeat
position: $x $y
.mail-icon
@include replace-text(url("/images/mail.svg"), 0)
CSS 輸出
.mail-icon {
text-indent: -99999em;
overflow: hidden;
text-align: left;
background-image: url("/images/mail.svg");
background-repeat: no-repeat;
background-position: 0 50%;
}
💡 小知識
預設值可以是任何 SassScript 表達式,它們甚至可以參考先前的參數!
關鍵字參數關鍵字參數永久連結
引入 mixin 時,除了透過它們在參數列表中的位置傳遞之外,還可以透過名稱傳遞參數。這對於具有多個選用參數的 mixin,或者具有布林值參數(沒有名稱就無法清楚了解其含義)的 mixin 特別有用。關鍵字參數使用與變數宣告和選用參數相同的語法。
SCSS 語法
@mixin square($size, $radius: 0) {
width: $size;
height: $size;
@if $radius != 0 {
border-radius: $radius;
}
}
.avatar {
@include square(100px, $radius: 4px);
}
Sass 語法
@mixin square($size, $radius: 0)
width: $size
height: $size
@if $radius != 0
border-radius: $radius
.avatar
@include square(100px, $radius: 4px)
CSS 輸出
.avatar {
width: 100px;
height: 100px;
border-radius: 4px;
}
⚠️ 注意!
因為任何參數都可以透過名稱傳遞,所以在重新命名 mixin 的參數時要小心…它可能會破壞使用者的程式碼!將舊名稱保留一段時間作為選用參數,並在有人傳遞它時印出警告訊息,以便他們知道要遷移到新的參數,這會很有幫助。
接受任意參數接受任意參數永久連結
有時,讓 mixin 能夠接受任意數量的參數會很有用。如果 @mixin
宣告中的最後一個參數以 ...
結尾,則該 mixin 的所有額外參數都會以列表的形式傳遞給該參數。這個參數稱為參數列表。
SCSS 語法
@mixin order($height, $selectors...) {
@for $i from 0 to length($selectors) {
#{nth($selectors, $i + 1)} {
position: absolute;
height: $height;
margin-top: $i * $height;
}
}
}
@include order(150px, "input.name", "input.address", "input.zip");
Sass 語法
@mixin order($height, $selectors...)
@for $i from 0 to length($selectors)
#{nth($selectors, $i + 1)}
position: absolute
height: $height
margin-top: $i * $height
@include order(150px, "input.name", "input.address", "input.zip")
CSS 輸出
input.name {
position: absolute;
height: 150px;
margin-top: 0px;
}
input.address {
position: absolute;
height: 150px;
margin-top: 150px;
}
input.zip {
position: absolute;
height: 150px;
margin-top: 300px;
}
接受任意關鍵字參數接受任意關鍵字參數永久連結
參數列表也可以用於接受任意關鍵字參數。meta.keywords()
函式接受一個參數列表,並將傳遞給 mixin 的任何額外關鍵字作為映射(從參數名稱(不包括 $
)到這些參數的值)返回。
SCSS 語法
@use "sass:meta";
@mixin syntax-colors($args...) {
@debug meta.keywords($args);
// (string: #080, comment: #800, variable: #60b)
@each $name, $color in meta.keywords($args) {
pre span.stx-#{$name} {
color: $color;
}
}
}
@include syntax-colors(
$string: #080,
$comment: #800,
$variable: #60b,
)
Sass 語法
@use "sass:meta"
@mixin syntax-colors($args...)
@debug meta.keywords($args)
// (string: #080, comment: #800, variable: #60b)
@each $name, $color in meta.keywords($args)
pre span.stx-#{$name}
color: $color
@include syntax-colors($string: #080, $comment: #800, $variable: #60b)
CSS 輸出
pre span.stx-string {
color: #080;
}
pre span.stx-comment {
color: #800;
}
pre span.stx-variable {
color: #60b;
}
💡 小知識
如果您從未將參數列表傳遞給 meta.keywords()
函數,則該參數列表將不允許額外的關鍵字參數。這有助於您的 mixin 的呼叫者確保他們沒有意外拼錯任何參數名稱。
傳遞任意參數傳遞任意參數 永久連結
就像參數列表允許 mixin 接收任意位置或關鍵字參數一樣,相同的語法也可用於將位置和關鍵字參數*傳遞*給 mixin。如果您在 include 的最後一個參數傳遞一個列表後加上 ...
,其元素將被視為額外的 positional 參數。同樣地,加上 ...
的 map 將被視為額外的 keyword 參數。您甚至可以同時傳遞兩者!
SCSS 語法
$form-selectors: "input.name", "input.address", "input.zip" !default;
@include order(150px, $form-selectors...);
Sass 語法
$form-selectors: "input.name", "input.address", "input.zip" !default
@include order(150px, $form-selectors...)
💡 小知識
因為 參數列表 會同時追蹤位置和關鍵字參數,您可以使用它一次將兩者傳遞給另一個 mixin。這使得定義 mixin 的別名變得非常容易!
內容區塊內容區塊 永久連結
除了接收參數之外,mixin 還可以接收整個樣式區塊,稱為*內容區塊*。Mixin 可以通過在其主體中包含 @content
at-rule 來宣告它接收一個內容區塊。內容區塊像 Sass 中的任何其他區塊一樣使用大括號傳入,並且它會被注入到 @content
規則的位置。
SCSS 語法
@mixin hover {
&:not([disabled]):hover {
@content;
}
}
.button {
border: 1px solid black;
@include hover {
border-width: 2px;
}
}
Sass 語法
@mixin hover
&:not([disabled]):hover
@content
.button
border: 1px solid black
@include hover
border-width: 2px
CSS 輸出
.button {
border: 1px solid black;
}
.button:not([disabled]):hover {
border-width: 2px;
}
💡 小知識
一個 mixin 可以包含多個 @content
at-rule。如果有的話,內容區塊將會為每個 @content
分別包含。
⚠️ 注意!
內容區塊是*詞法作用域*的,這表示它只能看到包含 mixin 的作用域中的 局部變數。它看不到在其傳遞到的 mixin 中定義的任何變數,即使它們是在呼叫內容區塊之前定義的。
將參數傳遞給內容區塊將參數傳遞給內容區塊 永久連結
- Dart Sass
- 自 1.15.0 起
- LibSass
- ✗
- Ruby Sass
- ✗
Mixin 可以通過編寫 @content(<arguments...>)
將參數傳遞給其內容區塊,就像將參數傳遞給另一個 mixin 一樣。編寫內容區塊的使用者可以通過編寫 @include <name> using (<arguments...>)
來接收參數。內容區塊的參數列表的工作方式就像 mixin 的參數列表一樣,而 @content
傳遞給它的參數的工作方式就像將參數傳遞給 mixin 一樣。
⚠️ 注意!
如果 mixin 將參數傳遞給其內容區塊,則該內容區塊*必須*宣告它接受這些參數。這表示最好只按位置(而不是按名稱)傳遞參數,並且這表示傳遞更多參數是一個破壞性變更。
如果您希望在傳遞給內容區塊的資訊方面具有彈性,請考慮傳遞一個包含它可能需要的資訊的 map!
SCSS 語法
@mixin media($types...) {
@each $type in $types {
@media #{$type} {
@content($type);
}
}
}
@include media(screen, print) using ($type) {
h1 {
font-size: 40px;
@if $type == print {
font-family: Calluna;
}
}
}
Sass 語法
@mixin media($types...)
@each $type in $types
@media #{$type}
@content($type)
@include media(screen, print) using ($type)
h1
font-size: 40px
@if $type == print
font-family: Calluna
CSS 輸出
@media screen {
h1 {
font-size: 40px;
}
}
@media print {
h1 {
font-size: 40px;
font-family: Calluna;
}
}
縮排 Mixin 語法縮排 Mixin 語法 永久連結
縮排語法 除了標準的 @mixin
和 @include
之外,還有一種特殊的語法用於定義和使用 mixin。Mixin 使用字元 =
定義,並使用 +
包含。雖然這種語法更簡潔,但它也更難一眼理解,建議使用者避免使用它。
Sass 語法
=reset-list
margin: 0
padding: 0
list-style: none
=horizontal-list
+reset-list
li
display: inline-block
margin:
left: -2px
right: 2em
nav ul
+horizontal-list
CSS 輸出
nav ul {
margin: 0;
padding: 0;
list-style: none;
}
nav ul li {
display: inline-block;
margin-left: -2px;
margin-right: 2em;
}