論原子 CSS 的日益普及

sunshine小小倩發表於2019-03-04

論原子 CSS 的日益普及

即使你自認為是 CSS 方面的專家,也很可能在某一大型專案中,處理一個錯綜複雜並且越來越龐大的樣式表,它們中一些樣式表看起來就像一張相互繼承並且混亂纏繞的網。

義大利麵怪物

級聯的作用非常強大。微小的改變可能會引起很大的改變,這就導致了很難知道下一秒會發生什麼。重構、更改和移除 CSS 都是高危動作,因為很難知道這個 CSS 在哪裡被引用。

你什麼時候可以做到改變 CSS 不引起不必要的改動? 答案是無論在何種情況下,你都很少有這種想法。

在我有限的經驗中,其中的一種情況是,在大型團隊的大型程式碼庫中,給人的感覺是 CSS 太大了以至於團隊的成員開始對 CSS 很敏感並且對 CSS 感到害怕,但是實際上只是讓你增加 CSS。

由此產生一個工具,它能做的事情遠遠少於 CSS,但是在某種程度上(在你學會之後),沒有人在對其感到害怕,我認為這非常棒。

原子 CSS 讓事情變得簡單

我不在需要去考慮如何組織我的 CSS。我也不需要考慮如何給我的元件起名,也不需要考慮將一個元件和另一個元件完全分離,應該將其放在哪裡,最重要的,當有新的需求是怎麼進行重構。

原子 CSS 提供了一套直接、明顯並且簡單的方法論。類是不可變的,你不可以改變類名。這使得s使用 CSS 是可預見的和可靠的,因為類總是做完全相同的事情。在 HTML 檔案中新增或者移除一個有作用域範圍的公用類是明確的,它讓你確信你不會破壞其他任何東西。這可以減少認知負荷和精神負擔。

給元件命名是出了的困難。想出一個既有意義又足夠通用的類名費時又費力。

電腦科學中只有兩個難題:快取失效和命名問題。

– Phil Karlton

提出適當的抽象是困難的。相比之下,命名工具類就簡單直接一些。

/* 工具類命名 */
.relative {
  position: relative;
}
.mt10 {
  margin-top: 10px;
}
.pb10 {
  padding-bottom: 10px;
}
複製程式碼

原子的類從名字就可以知道它們的功能。意圖和效果顯而易見。而包含無數類名的 HTML 會顯得很亂,HTML 比一個龐大並且錯綜複雜的樣式要容易一些。

在一個前後端混合的團隊中,可能參與開發的後臺人員對 CSS 知識有限,很少有人將樣式表搞亂。

來自 ryanair.com —— 整個 CSS 都在完成一個效果

樣式差異處理

工具類 非常適合處理小的樣式差異。雖然設計系統和模式庫現在可能風靡一時,但是你要意識到將會有不斷的新需求和變化。所有元件的可重用性往往不是體現在設計模擬。雖然實現和設計稿一致是最好的,但是一個大型網站繁多的上下環境一定會有很多的不可避免的不同。

論原子 CSS 的日益普及

Medium 的開發團隊已經不使用 BEM 了,在 他們的博文中 有提到。

如果我們希望元件通過簡單的方式和另一個元件只有細微的差別,該怎麼去做呢?如果你使用的 BEM 的命名方式,修飾符類很可能會不起作用。無數的修飾符往往只有一個效果。我們以邊距(margin)為例。不同元件的邊框大部分都不相同,讓所有元件的邊框保持一致也不太可能。這個距離不僅取決於元件,還取決於元件在頁面中的位置和它相對於其他元素的相對位置。大部分的設計都包含相似但是不完全相同的 UI 元素,使用傳統的 CSS 很難處理。

很多人都不喜歡它

Aaron Gustafson,《A List Apart》的總編輯,Web Standards Project 的前任專案經理,微軟員工

Soledad Penades,來自 Mozilla 的工程師

CSS 禪意花園的創辦者

原子 CSS 和行內樣式有什麼不同?

這是質疑原子 CSS 的人經常會問到的問題。長期以來大家都認為行內樣式不利於實踐,自 Web 時代初期就很少有人使用了。**那些批評者將原子 CSS 與行內樣式等同也是有道理的,因為行內元素和原子 CSS 有相同的弊端。**舉個例子,如果我們想要將所有的 .block 類中的 color 改變為 navy 會怎樣?如果這樣做:

.black {
  color: navy;
}
複製程式碼

很明顯,這是不對的。

現在的編輯器很複雜。使用查詢和替換將所有的 .black 類換成一個新的 .navy 類十分的簡單,但是卻是很危險的。問題是,你只是想將 某些 .block 類變為 .naby 類。

在傳統的 CSS 方法中,調整元件的樣式和在一個 CSS 檔案中更新一個類的一個值一樣簡單。使用原子 CSS,這就變成了一項單調乏味的任務,它通過搜尋每一塊 HTML 來更新所述元件的每一個例項。然而所有的高階編輯器都是這樣。即使你將標記分離為可重用的模板,這仍然是一個主要缺點。也許這種手動操作對於這種簡單的方法是值得的。用不同的類更新 HTML 檔案可能很乏味,但並不困難。(雖然有一些時候我在手動更新時遺漏了相關元件的某些例項,暫時引入了風格不一致)。如果改變了設計,你可能需要從 HTML 中手動編輯類。

雖然原子 CSS 和內聯樣式一樣有很大的缺陷,但是這不是一種退後。工具類以各種方式優於內聯樣式。

原子 CSS vs. 行內樣式

原子類允許抽象,內聯樣式不允許

原子類可以建立抽象類,內聯樣式不行。

<p style="font-family: helvetica; color: rgb(20, 20, 20)">
  Inline styles suck.
</p>
<p class="helvetica rgb202020">
  Badly written CSS isn't very different.
</p>
<p class="sans-serif color-dark">
  Utility classes allow for abstraction.
</p>
複製程式碼

當改變設計的時候,上面例子的前兩個需要手動的修改和替換。第三個例子可以只調整一處樣式表。

工具

CSS 社群已經建立了很多用於行內樣式的無用的工具例如:Sass, Less, PostCSS, Autoprefixer 等。

更加簡潔

與其寫出冗餘的行內樣式,倒不如像原子 CSS 一樣寫出簡潔的宣告縮寫。相比之下少打了一些字元:mt0margin-top: 0flexdisplay: flex,等等。

差異性

這是一個有爭議的話題。如果一個類或者行內樣式僅僅只做一件事情,那麼你是否希望它只做一件事情,很多人提倡使用 !importent 來保證不被其他的除了 !important 的樣式重寫,這也就意味著這個樣式肯定會被應用。但是,一個類本身是足夠具體的,可以覆蓋其他的基本類。和行內樣式相比,原子類特異性較低是一件好事。它允許更多的通用性。都可以使用 JavaScript 來改變樣式。如果是行內樣式的話就比較困難。

樣式表的類比行內樣式能做的更多

行內樣式不支援媒體查詢、偽選擇器、@supports 和 CSS 動畫。也許你有一個單獨的懸停效果你想要應用在不同的元素而不是一個元件。

.circle {
  border-radius: 50%;
}

.hover-radius0:hover {
  border-radius: 0;
}
複製程式碼

簡單的可重用媒體查詢規則也可以轉換成實用的工具類,其常用的類名字首表示小型、中型和大型的螢幕尺寸。下面有一個 flexbox 類的例項,只能對中型和大型螢幕尺寸有效:

@media (min-width: 600px) {
  .md-flex {
    display: flex;
  }
}
複製程式碼

這在內聯樣式中是不可能的。

你是不是想要一個可重用的有偽內容的圖示或標籤?

.with-icon::after {
  content: 'some icon goes here!';
}
複製程式碼

有限的選擇可能會更好

行內樣式可以做任何事情。這過於自由以至於很容易導致顯示效果混亂和不一致。通過每一個預定類,原子 CSS 可以保證一定程度的風格一致。而不是雜亂的顏色值和不確定的顏色值,工具類提供了一個預定義設定選項。開發者從有限的設定中選擇單一功能的工具類,這種約束既可以消除日益增加的樣式問題,保持視覺的一致性。

我們來看一個 box-shadow 的例子。一個行內樣式可以隨意使用偏移量、範圍、顏色、透明度和模糊半徑。

<div style="box-shadow: 2px 2px 2px rgba(10, 10, 250, .4)">stuff</div>
複製程式碼

使用原子方法,CSS 作者可以定義首選樣式,然後簡單應用,不可能出現風格不一致。

<div class="box-shadow">stuff</div>
複製程式碼

原子 CSS 既不是全能也不是一無是處

毫無疑問,像 Tachyons 這樣的原子類框架越來越受歡迎。然而,CSS 方法並不是互斥的。很多情況下,工具類並不是最好的選擇:

  • 如果你需要在媒體查詢中改變特定元件裡面大量的樣式。
  • 如果你想要使用 JavaScript 改變很多樣式,將其抽象為一個單獨的類是非常容易的。

原子類可以和其他樣式方法共存。我們應該將設定一些基礎類和穩健的全域性樣式。如果你繼續複製工具類的相似字串,這些樣式很可能被抽象為一個類。你可以在元件類中將其合併,但是你只能在知道它們不會被重用時才可以這樣。

以元件為先的方法去寫 CSS 意味著你建立一個元件事物即使他們不會再被重用。這種過早的抽象就是使樣式表變得冗餘和複雜的原因。

單位越小,它的可重用性就越強。

看一下 Bootstrap 的最新版本,現在提供了一整套的工具類,仍然包括其傳統的元件。未來,越來越多的流行框架採用這種混合方法。


掘金翻譯計劃 是一個翻譯優質網際網路技術文章的社群,文章來源為 掘金 上的英文分享文章。內容覆蓋 AndroidiOS前端後端區塊鏈產品設計人工智慧等領域,想要檢視更多優質譯文請持續關注 掘金翻譯計劃官方微博知乎專欄

相關文章