Utility-First CSS 的崛起:以 Tailwind CSS 為例

4 分鐘

1. 傳統 CSS 方法論的困境

在 Utility-First 出現之前,我們有許多優秀的 CSS 方法論來組織樣式,例如:

  • BEM (Block, Element, Modifier): 透過 block__element--modifier 的命名約定來保證樣式的獨立性和可維護性。
  • OOCSS (Object-Oriented CSS): 提倡將結構與外觀分離,以及容器與內容分離。
  • CSS-in-JS: 將 CSS 直接寫入 JavaScript 元件中,實現了元件層級的樣式封裝。

這些方法在一定程度上解決了 CSS 全域污染和程式碼組織的問題,但通常也帶來了新的問題:為無數的 class 命名所耗費的心力、檔案切換的繁瑣,以及 CSS-in-JS 可能帶來的執行階段開銷。

2. 什麼是 Utility-First?

Utility-First(功能優先)是一種 CSS 思想,它主張提供一系列 單一用途、命名不變的功能類別,然後透過組合這些類別來建構複雜的 UI。

例如,你不會去寫一個 .card 類別,然後在 CSS 檔案裡定義它的 displaypaddingbox-shadow。 取而代之的是,你直接在 HTML 中這樣寫:

<div class="block p-6 rounded-lg shadow-lg bg-white">
  <!-- ... -->
</div>

這裡的 blockp-6rounded-lg 等都是功能類別,它們各自只負責一件小事。

3. Tailwind CSS:Utility-First 的典範

Tailwind CSS 是目前最流行的 Utility-First CSS 框架。它提供了一套極其詳盡的功能類別,幾乎涵蓋了所有常用的 CSS 屬性。

核心優勢:

  • 極速開發: 你幾乎不需要離開 HTML 檔案。透過組合原子類別,可以快速建構出任何設計,極大地提升了原型設計和開發的效率。
  • 強制設計系統: 由於所有的樣式(顏色、間距、字號)都來自預先定義的設定 (theme),團隊成員可以輕鬆地保持 UI 的一致性,避免了「魔法數字」的出現。
  • 無需為命名煩惱: 「電腦科學兩大難題:快取失效和命名。」Tailwind 讓你基本告別了為 CSS 類別命名的煩惱。
  • 極致效能: 在正式環境建置時,Tailwind 會掃描你的檔案,透過 PurgeCSS(或內建的 JIT 引擎)移除所有未被使用的 CSS 類別,最終的 CSS 檔案體積通常會非常小。

4. 「類別名稱地獄」?—— 看待缺點的不同視角

對 Tailwind 最常見的批評就是它讓 HTML 變得非常臃腫,可讀性差,像是回到了「行內樣式」的時代。

<button class="py-2 px-4 font-semibold rounded-lg shadow-md text-white bg-blue-500 hover:bg-blue-700">
  Click me
</button>

這確實是一個需要適應的過程。但支持者認為:

  1. 樣式和結構本就緊密耦合,將它們放在一起反而更便於維護。
  2. 透過提取可重複使用的元件(如 React/Vue 元件),可以將這部分「混亂」封裝起來。

對於需要重複使用的樣式組合,Tailwind 提供了 @apply 指令:

/* in your css file */
.btn-primary {
  @apply py-2 px-4 font-semibold rounded-lg shadow-md text-white bg-blue-500 hover:bg-blue-700;
}

這樣你就可以在 HTML 中使用 .btn-primary 了。不過,Tailwind 官方更推薦透過元件化來解決重複使用問題。

結論

Utility-First 和 Tailwind CSS 的成功,標誌著前端開發在「關注點分離」上的理念轉變——從「語言的分離」 (HTML/CSS/JS) 轉向了「元件的分離」。它透過一種看似「原始」的方式,解決了現代 Web 開發中的許多實際痛點,為開發者提供了一條通往高效、一致和高效能 UI 的捷徑。