CSS原生語法 @function,讓原始碼也有程式功能

以前如果說 CSS 是「程式碼」的話,通常都會被糾正為「原始碼」,但在 @function 等功能性的語法出現之後,現在這個傳統界線也越來越模糊。

CSS @function() 用法

本文將透過之前提過的 if()sibling-index()、sibling-count() 語法,帶大家體驗 @function 的強大功能。

1. 結合 attr() 與型別定義的狀態樣式

過去我們使用 attr() 取值時,通常只能用於 content 屬性,且無法參與運算或邏輯判斷。新的語法允許我們指定型別 type(<custom-ident>),這讓 HTML 的屬性值可以被 CSS 的 if() 邏輯正確識別。

在這個範例中,我們定義了一個 --status-color 函數,它接收一個狀態參數,並根據傳入的值決定回傳的顏色。你可以注意到,它和 JavaScript 一樣可以設定變數的預設值:


@function --status-color(--status: xxx, --success: #7dfaa5, --error: #ff3874) {
  result: if(
    style(--status: success): var(--success);
    style(--status: error): var(--error);
    else: #fccd81
  );
}

.card {
  /* 使用 attr() 抓取 HTML 的 data-status,並強制轉型為 custom-ident */
  background-color: --status-color(attr(data-status type(<custom-ident>)));
}

跟 JavaScript 不同的地方在於,JS 是用 return 拋出結果,CSS 則是用 result:

這樣的寫法讓我們可以直接在 HTML 中控制語意,而樣式的邏輯完全封裝在 CSS 函數內:

<div class="card" data-status="error">error</div>
<div class="card" data-status="success">success</div>
<div class="card" data-status="else">else</div>

2. 感知數量的樣式:sibling-count()

下方的 --count-color 函數會檢查同層級的元素數量,若大於 3 個,則回傳紫色,否則回傳預設的橘黃色:

@function --count-color() {
  result: if(
    style(sibling-count() > 3): #9b59b6;
    else: #fccd81
  );
}

.card {
  background-color: --count-color();
}

這對於響應式容器查詢或動態內容的樣式調整非常有幫助,因為它直接反映了 DOM 結構的數量狀態。

3. 感知位置的樣式:sibling-index()

除了數量之外,我們也可以透過 sibling-index() 取得當前元素在同層級中的索引值。

在這個範例中,當元素的索引值大於 3 的時候,背景會自動轉為藍色:

@function --index-color() {
  result: if(
    style(sibling-index() > 3): #64c5fa;
    else: #fccd81
  );
}

.card {
  background-color: --index-color();
}

但要注意,JS 索引是從0開始,CSS的索引是從1開始。

最後,附上 codepen 給大家有視覺化的參考:

See the Pen CSS @function + if() by cj (@cjzopen) on CodePen.

總結

透過 @functionif(),CSS 正式具備了類似程式語言的邏輯處理能力。我們不再需要為了簡單的狀態切換而頻繁地在 class 之間切換,或是依賴預處理器的編譯。這不僅讓程式碼更精簡,也讓樣式與結構的耦合度降到最低。

不過,目前仍只有使用Chromium為核心的瀏覽器支援,期待未來各家瀏覽器支援度的提升,讓這些原生的邏輯功能成為 CSS 架構中的核心工具。

留言

這個網誌中的熱門文章

如何產生醒目顯示文字的連結?讓使用者一目瞭然的功能(Scroll to Text Fragment)

用CSS的 min max與vw cqw,設計有極限值的RWD響應式文字

Google Search Console 網頁發現方式多了「參照網頁」