Utility-First CSS 的崛起:以 Tailwind CSS 為例
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 檔案裡定義它的 display、padding、box-shadow。 取而代之的是,你直接在 HTML 中這樣寫:
<div class="block p-6 rounded-lg shadow-lg bg-white">
<!-- ... -->
</div>這裡的 block、p-6、rounded-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>這確實是一個需要適應的過程。但支持者認為:
- 樣式和結構本就緊密耦合,將它們放在一起反而更便於維護。
- 透過提取可重複使用的元件(如 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 的捷徑。