使用 CSS 函式減少樣式重複

網路功能: @function

維護大型樣式表時,經常會出現重複的邏輯,尤其是在處理漸層或回應式版面配置模式等設計系統權杖時。

CSS @function at 規則可讓您將這項邏輯封裝成可重複使用的參數化函式,讓 CSS 更易於維護、一致且 DRY (不重複)。

@function 語法

自訂函式是使用 @function 規則定義,後面接著以虛線分隔的名稱和參數清單。函式會使用 result 屬性傳回值。

@function --my-function(--input1 <length>, --input2: default-value) returns <length> {
  /* Logic goes here */
  result: var(--input1);
}

核心概念

  • 參數:開頭必須是雙破折號 (--)。
  • 預設值:您可以使用冒號 (:) 提供預設值。
  • 結果:result 屬性會決定函式傳回的值。函式主體中最後宣告的 result 會勝出。
  • 範圍:在函式內定義的參數和變數,範圍僅限於函式內部。
  • 類型:您可以使用括號標記法 (例如 <color>) 要求參數和傳回值符合 CSS 類型,並使用 type 函式 (例如 type(<number> | <percentage>)) 允許使用多種類型。

實際範例

1. 設計系統權杖 (漸層)

封裝漸層邏輯,確保應用程式中的顏色漸層一致。--angle 提供預設值,確保一致性,但可覆寫。

@function --fancy-gradient(--start-color <color>, --end-color <color>, --angle: 98deg) returns <image>{
  result: linear-gradient(in oklab var(--angle), var(--start-color), var(--end-color) );
}

.card {
  background: --fancy-gradient(#ed73d7, #5d87e9);
}

2. 條件式版面配置邏輯

您可以直接在函式中使用 @media 或其他查詢,根據環境傳回不同的值。在函式中使用條件邏輯時,請注意 @function 不會在 result 的第一個值「傳回」,而是會遵循 CSS 階層,並根據螢幕大小、容器大小或其他查詢,解析為最後一個相符的值。

@function --grid-template(--count <number>){
  /* MANDATORY: Put default value first. */
  result: 1fr; /* Default: stack */
  @media (min-width: 800px) {
    result: repeat(var(--count), 1fr); /* Grid on larger screens */
  }
}

main {
  display: grid;
  grid-template-columns: --grid-template(2);
}

最佳做法

  • 使用虛線名稱:一律在函式名稱和參數前加上 --。
  • 提供預設值:提供合理的預設值,讓函式更穩健。
  • 保持簡潔:只在邏輯確實重複或複雜時使用函式。請勿過度設計簡單的屬性/值組合。
  • 使用類型:確保參數和傳回值符合預期類型。
  • 考慮使用預先編譯的替代方案:如果函式不依賴使用者輸入、媒體查詢或其他用戶端變化版本,建議使用 CSS 預先編譯器,避免在用戶端執行不必要的工作。

備用策略

在不支援 CSS 函式的瀏覽器中,使用 CSS 函式設定的值將無效。如要支援其他瀏覽器,請先為屬性提供備用值。在支援 CSS 函式的瀏覽器中,這項設定會遭到覆寫。

.card {
  /* Provide fallback, in this case a solid color. */
  background: #5d87e9;
  background: --fancy-gradient(#ed73d7, #5d87e9);
}

main {
  /* Provide fallback, in this case a simple stacked default. */
  grid-template-columns: 1fr;
  grid-template-columns: --grid-template(2);
}

如果必須減少樣式重複,同時支援其他瀏覽器,請考慮使用具有函式的 CSS 預編譯器,例如 Sass。