SASS中的Mixins
本文說明了SASS中的Mixins。
我們將通過實際範例說明SASS中的Mixins。
YouTube Video
SASS中的Mixins
概述 — 什麼是Mixin?
混合(Mixins)是一種機制,允許您將常用的一組樣式屬性定義為可重複使用的函數,並可在需要的地方調用。它們對於讓你的CSS類別及多個屬性保持DRY(不重複自己)非常有用。
範例:最簡單的Mixin
以下是一個簡單的Mixin範例,可同時重複使用border-radius和box-shadow。通過調用這個Mixin,你可以將相同的外觀套用到多個元素上。
1// Simple mixin that applies border-radius and box-shadow
2@mixin card-style {
3 border-radius: 8px;
4 box-shadow: 0 4px 10px rgba(0, 0, 0, 0.12);
5 background: #fff;
6}
7
8.card {
9 @include card-style;
10 padding: 1rem;
11}- 使用此Mixin,你無需再直接重複編寫樣式。
- 只需一行即可調用:
@include card-style;。
帶參數(參數化)的Mixin
Mixin可以像函式一樣接受參數。這讓你可以用相同邏輯變化外觀。接下來是以顏色作為參數的範例。
1// Mixin with parameters: accepts a color and optional radius
2@mixin colored-box($bg-color, $radius: 4px) {
3 background-color: $bg-color;
4 border-radius: $radius;
5 padding: 0.75rem;
6}
7
8.box-primary {
9 @include colored-box(#007acc);
10}
11
12.box-custom {
13 @include colored-box(#ffcc00, 12px);
14}- 通過設置預設值,可以控制當省略參數時的行為。
- 在此範例中,半徑用預設值,只覆蓋背景顏色。
使用可變參數(...)的情況
當需要接受多個值時,可以使用可變參數($args...)。這對於生成工具類別或傳遞後備列表很有用。
當你需要傳遞多個字型系列或多個陰影值時非常有用。
1// Mixin that accepts variable arguments and forwards them to box-shadow
2@mixin multi-shadow($shadows...) {
3 box-shadow: $shadows;
4}
5
6.panel {
7 @include multi-shadow(0 2px 4px rgba(0,0,0,0.08), 0 8px 16px rgba(0,0,0,0.06));
8}- 在調用端,可以用逗號分隔傳遞多個陰影值。
- 這樣,你可以用同一個Mixin處理簡單和複雜的陰影。
帶有@content的Mixin — 接收區塊
利用@content,Mixin可以從調用者接收一個樣式區塊。這讓Mixin能提供共同包裝器,調用者則指定內部細節。
1// Mixin that sets up a responsive container and yields to caller via @content
2@mixin responsive-container($max-width: 1200px) {
3 margin-left: auto;
4 margin-right: auto;
5 padding-left: 1rem;
6 padding-right: 1rem;
7 max-width: $max-width;
8
9 @content; // place where caller's styles are inserted
10}
11
12.header {
13 @include responsive-container(1000px) {
14 display: flex;
15 align-items: center;
16 justify-content: space-between;
17 }
18}- 在調用端,你可以在
@include裡加入樣式區塊來插入內部樣式。 - 此模式對於layout包裝(如網格、卡片、表單)很有用。
進階Mixin應用:條件與迴圈
在Mixin中可以使用@if和@for等控制結構。你可以用它們自動產生工具類別,並集中管理響應式設置。
以下是自動生成工具類別寬度的範例。
1@use 'sass:math';
2
3// Mixin that generates width utility classes from a list of fractions
4@mixin generate-widths($fractions) {
5 @each $name, $fraction in $fractions {
6 .w-#{$name} {
7 width: math.percentage($fraction);
8 }
9 }
10}
11
12$widths: (
13 '1-4': 0.25,
14 '1-3': 0.3333,
15 '1-2': 0.5,
16 '3-4': 0.75
17);
18
19@include generate-widths($widths);- 只需在調用端傳遞您想要生成的分數映射,就可以一次性自動生成對應的工具類。
- 使用這種方法的優點是減少了手動定義樣式,同時保持設計的一致性。
Mixin 與 Placeholders(%placeholder)比較
混合(mixins)直接插入一組屬性,而佔位符則在繼承樣式時與 @extend 一起使用。在某些情況下,mixins 可能產生重複的 CSS,但 @extend 在某些時候能生成更精簡的 CSS。
通過了解每種方法生成的 CSS 的目的及差異,您將能夠選擇最合適的方式。
1// Placeholder example (for comparison)
2%btn-base {
3 display: inline-block;
4 padding: 0.5rem 1rem;
5 border-radius: 4px;
6}
7
8.btn-primary {
9 @extend %btn-base;
10 background: #007acc;
11 color: #fff;
12}
13
14.btn-secondary {
15 @extend %btn-base;
16 background: #e0e0e0;
17}- 當您使用
@extend繼承佔位符時,能將多個選擇器合併為一條規則,從而生成更精簡的 CSS。 - 另一方面,因為 mixins 會在需要的地方直接插入屬性,所以具有靈活性,也能避免不必要的選擇器合併。
常見實用模式(響應式、瀏覽器前綴等)
在實務中,將瀏覽器前綴和響應式等通用處理放入Mixin會很有幫助。以下是結合transform與前綴屬性的範例。你可以集中管理相容性程式碼,讓維護變得更簡單。
1// Mixin for transform with vendor prefixes
2@mixin transform($value) {
3 -webkit-transform: $value;
4 -ms-transform: $value;
5 transform: $value;
6}
7
8.icon-rotate {
9 @include transform(rotate(45deg));
10}- 使用方式簡單,您可以在任何地方使用,例如:
@include transform(rotate(10deg));。 - 即使未來前綴變得不再需要,只要更新 mixin,全專案都會反映改動,因此維護會更加輕鬆。
實用範例:結合卡片與按鈕
以下是一個範例,展示如何使用mixin將卡片內的按鈕樣式統一,並且可以根據主題顏色進行切換。
這種作法讓'卡片+按鈕'這類常用模式能夠透過Mixin統一管理。
1// Simple mixin that applies border-radius and box-shadow
2@mixin card-style {
3 border-radius: 8px;
4 box-shadow: 0 4px 10px rgba(0, 0, 0, 0.12);
5 background: #fff;
6}
7
8// Mixin for transform with vendor prefixes
9@mixin transform($value) {
10 -webkit-transform: $value;
11 -ms-transform: $value;
12 transform: $value;
13}
14
15// Button mixin with theme and size parameters
16@mixin btn($bg, $color: #fff, $padding: 0.5rem 1rem) {
17 display: inline-block;
18 padding: $padding;
19 background: $bg;
20 color: $color;
21 border-radius: 6px;
22 text-decoration: none;
23 cursor: pointer;
24 @include transform(translateY(0)); // reuse earlier transform mixin
25}
26
27// Card mixin that accepts inner button styling via @content
28@mixin card($gap: 1rem) {
29 @include card-style; // reuse earlier card-style mixin
30 padding: $gap;
31 @content;
32}
33
34.card-feature {
35 @include card {
36 .title { font-size: 1.125rem; margin-bottom: 0.5rem; }
37 .cta {
38 @include btn(#007acc);
39 }
40 }
41}
42
43.card-warning {
44 @include card {
45 .title { font-weight: bold; }
46 .cta {
47 @include btn(#ff6600);
48 }
49 }
50}- 利用這些Mixin,你可以更簡潔地編寫元件。
注意效能與生成的CSS
由於每次調用Mixin都會插入樣式,若同一規則反覆用@include,生成的CSS會變大。可以根據需要配合Placeholder和元件設計進行優化。
此外,下列措施也很有效。
- 經常使用的樣式應該製作成類別以便重複使用。
- 常用的模式應該使用
@content來組合。 - 複雜的工具類產生應該只在建構時進行。
便於除錯的小技巧
在使用mixin時,設計提升除錯及維護性的辦法也很重要。透過使用清晰的變數名稱並在 mixins 內加入註釋,日後回顧代碼時會更容易理解。此外,如果功能變得複雜,將mixin拆分為較小的單元會讓測試更容易,也能提升維護性。
另外,啟用原始碼對應(source map)可以更輕鬆地追蹤是哪個mixin產生了哪段CSS,方便排查問題。
以下是一個附有說明註解且容易理解的mixin範例。
1// Example: readable mixin with clear param names and comments
2/// Adds a subtle focus ring for accessibility
3/// $color - ring color
4/// $size - thickness of the ring
5@mixin focus-ring($color: #007acc, $size: 2px) {
6 outline: none;
7 box-shadow: 0 0 0 $size rgba(blue($color), 0.15);
8}- 擁有這樣有條理的說明註解,可以讓團隊內部更容易分享與理解。
- 由於SASS的說明註解可以被相容工具自動提取,也適合用來生成像樣式指南等文件。
總結
Mixin可將常用樣式整合後重複使用,降低程式碼重複度並改善維護性。另外,當多個選擇器共用同一規則時,也可考慮混合使用Mixin與@extend(Placeholders)。此外,雖然@content能靈活分離排版包裝與內容,但過度使用@include會使CSS變得肥大,請注意。善用參數、預設值與可變參數來設計具有通用性並易於擴展的Mixin非常重要。
您可以在我們的 YouTube 頻道上使用 Visual Studio Code 來跟隨上述文章一起學習。 請也查看我們的 YouTube 頻道。