SASS中的Mixins

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 頻道。

YouTube Video