CSS架構之 ACSS

CSS架構之 ACSS.png

系列文章

目錄

  • 前言
  • ACSS 的概念
  • ACSS 和 CSS-in-JS 為什么會火
  • ACSS 優劣
  • 如何選擇 ACSS 庫
  • 總結
  • 參考

前言

我們知道現在前端開發模式,組件化是比較火的,那么 CSS 開發模式比較火的是什么呢,沒錯就是我們今天的主角 ACSS,我們先觀察下各大型網站的應用:

Twitter 上的 HTML 是這樣的:

chrome Twitter

Facebook HTML 是這樣的::

chrome Facebook

最后看看 GitHub 的首頁:

等等……

看到 Twitter、Facebook 的類名你可能會嚇一跳,但是那也是 ACSS 的一種,相對來講 GitHub ACSS 更加符合你的直觀,無論如何,這么多大公司都用到了 ACSS,說明它確實有效,你應該也要在項目多多嘗試嘗試。

接下來我們進入 ACSS 的學習。

ACSS 的概念

ACSS 是 Atomic CSS 的簡寫,它是 Thierry Koblenz 在 2013 年 10 月的文章 Challenging CSS Best Practices 中創造的。

首先,讓我們為 原子化 CSS (Atomic CSS) 給出適當的定義:

John Polacek 在文章 Let’s Define Exactly What Atomic CSS is 中寫道:

Atomic CSS is the approach to CSS architecture that favors small, single-purpose classes with names based on visual function.

譯文:原子化 CSS 是一種 CSS 的架構方式,它傾向于小巧且用途單一的 class,并且會以視覺效果進行命名。

除了叫 ACSS,你還可以稱它為函數式 CSS,或者 CSS 實用工具。

CSS 是一個不強調邏輯,而更側重表現的一門所見即所得的語言,當樣式寫多了,你就會發現常用樣式的來來去去也就那幾個,無非就是調整一下他們的排列組合。每次寫這些重復的樣式代碼我就感覺自己是在重復造輪子,自然而然就產生了想要縮寫的需求,而 ACSS 做的一些事情很平常,無非就是把 CSS 屬性寫成一個獨立的類名。

.m-0 {
  margin: 0;
}
.text-red {
  color: red;
}
/* ... */

ACSS 和 CSS-in-JS 為什么會火

前面我們明白了 ACSS 的概念,所以接下來我要講下 CSS-in-JS 的概念,然后才好解釋為什么它們會火。

CSS-in-JS 是很重要的概念,本來打算寫篇文章介紹的,題目都取好了 「CSS 架構之 CSS-in-JS」,整理資料發現阮一峰老師寫過了,那我就直接拿過來吧 阮一峰——CSS in JS 簡介,但是阮老師并沒有給出流行 CSS 的解決方案,現在都 21 年了,我們知道目前流行著好幾種解決方案,方案各有利弊,我們需要一篇文章來通透的理解它們,于是 @FateRiddle 同學的 React拾遺:從10種現在流行的 CSS 解決方案談談我的最愛 (上) 這篇文章出現了。

你可以先不看上面的文章鏈接,我來給你梳理下:

很久以前,前端項目比較小,HTML、CSS、JS 都耦合在一起,后來隨著項目越來越大,為了便于維護,代碼不允許在耦合,要求各個技術只負責自己的領域。

在后來,伴隨著 React 出現,前端組織代碼的方式變了,組件成為組織代碼主流方法,而組件的核心原則就是代碼完全不依賴外部,表現在 React 中就是 HTML、CSS、JS 強強耦合,這樣就避免了影響其他組件,對于 CSS 我們也寫在了 JS 中,這就要 CSS in JS,其實就是寫行內樣式。

但行內樣式不支持偽類、媒體查詢,于是出現了 React-JSS 這種庫,對行內樣式進行擴展;有人又不能忍受 React-JSS 這種樣式駝峰的寫法;出現了 styled-components,遵循 CSS 寫法規范的庫;有人比較喜歡不耦合的寫法,于是 Css Module 出現了;還有人覺得 Vue 的解決辦法比較優雅,然后就出現了 styled-jsx。

我來總結下:

CSS-in-JS 本質就是行內樣式,之所以會火就是因為組件化時代的到來。

看明白 CSS in JS 火的原理,你肯定猜到 ACSS 會火的原因——那就是組件化時代的到來,你甚至可以理解為 ACSS 就是 CSS 架構下得 CSS 組件化。

在沒有組件化的傳統網頁開發時代,如果你通過 ACSS 來確定樣式,例如下面代碼的形式,合作的小伙伴肯定以為你瘋了:

<button class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">按鈕</button>

因為 button 的復用率很高,你項目到處充斥著這種 button,一旦 button 要修改某些樣式,你可去哭娘去吧,這哪有直接給個 .btn 類名方便,要修改直接改類名就行了,例如下面:

<button class="btn">按鈕</button>

但是在組件化時代就不一樣了,例如使用 React 封裝一個 Button:

const Button = ({ children, color }) => (
    <button class=`bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded ${color}`>{children}</button>
)

使用如下:

<Button color="pink"> 注冊 </Button>

如果樣式有修改,我只要插拔 ACSS 就行了,而且對比使用 .btn 實現,樣式的重用性會極大提高,理解也很容易。

這下你明白了嗎,要說 ACSS 和 CSS-in-JS 為什么會火,就是因為組件化

ACSS 優劣

使用 ACSS 的好處:

  • 你的 CSS 停止增長。使用傳統方法,每次添加新功能時,您的 CSS 文件都會變大。使用實用程序,一切都是可重用的,因此您很少需要編寫新的 CSS,一套樣式全局通用。
  • 你不是在浪費精力發明類名。不再添加愚蠢的類名,例如 sidebar-inner-wrapper 只是為了能夠設置樣式,也不再為真正只是一個 flex 容器的東西的完美抽象名稱而苦惱。
  • 靈活,易讀。CSS 是全球性的,當你做出改變時,你永遠不知道你破壞了什么。HTML 中的類是本地的,因此您可以 插拔式改變樣式 而不必擔心其他問題,CSS 樣式很多縮寫更加符合大腦的記憶。
  • 永遠不用擔心命名沖突,永遠不用擔心樣式覆蓋

使用 ACSS 劣處:

  • 毫無疑問,ACSS 會增加HTML 的體積,但是借助 Gzip 這個就不是大問題。
  • 熟悉命名 ACSS 命名會有一定成本。

ACSS 劣處是非常小的,而好處有非常大,沒有理由在項目中不適用,強烈建議你每個前端項目都是用 ACSS。

如何選擇 ACSS 庫

市面上有不少成熟的 CSS 框架,如 Tailwind CSSWindi CSS 以及 Tachyons 等。

同時有些 UI 庫也會附帶一些 CSS 工具類作為框架的補充,如 BootstrapChakra UI

甚至還有一些人根據項目總結出來自己的 ACSS,例如 atom.cssSACSS: Static Atomic CSS 等。

ACSS 庫大致就分為這三類了。

把它們整合到我們的項目,那我們選擇的標準是什么呢?

  1. 按需生成,比如我們使用 class="m-1" 來設置 margin,那么 m-x,x 到底是多大呢,x 但不管 x 是多大,當增加 x 的時候,margin 不同方向,比如 mt 代表 margin-topmb 代表 margin-bottom 等,也得增加,如果加上 :hover:focus 這樣的偽類時,體積還會得更變大,原子類太多了,應該提供按需生成只加載我們用過的。

  2. 動態化,原子類不應該是完全靜態化的,比如我要使用 class="m-100" ,我應該可以是直接使用,而不是設置完之后,發現樣式沒生效,然后通過框架的配置文件,去增加對 m-100 的支持,原子類要把可插拔做到極致。

除了上面兩個是非常重要的標準,我認為 自動值推導屬性化模式 也是提升了開發體驗要考慮的部分。

我們來看看我們最終會選擇哪個 ACSS 庫,首先原子 CSS 一定要純凈,所以 UI 框架附帶的 ACSS 就不能采用了,根據項目總結的 ACSS,它的原子 CSS 太過靜態,不能隨想隨用,不符合原子類不應該是完全靜態化的標準,Tailwind CSS 本來是沒有按需生成的,后來增加了,但是 Windi CSS 速度更快還兼容 Tailwind CSS,所以我們很自然就必須必的選擇了 Windi CSS

總結

我們先通過舉例子,了解了 ACSS 的使用,然后介紹了 ACSS 的概念,通過對比 CSS-in-JS 來剖析 ACSS 借助前端組件化浪潮開始起飛的過程,最后如何在項目中選擇自己的 ACSS 庫,我們通過一些硬性標準,分析了三類 ACSS 庫,幫你選擇了 Windi CSS

參考

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。