本篇文章將提到怎麼透過 BEM、SMACSS、OOCSS、Atomic CSS 的特性來:
- 縮短開發時間
- 減少需維護的程式碼
- 結構與樣式
CSS 選擇器和規則們就像女孩化妝桌上的化妝品們,桌上總是放著各個種類,數也數不清大罐小罐擠的噴的擦的,在沒有預備知識和整理規劃的情況下,若要一個男孩子短時間搞清楚簡直是天方夜譚。
當交接新專案的時候看到幾千行的樣式檔大概也是這樣的心情,一般專案在未規範的情況下,通常都會發展為幾千甚至幾萬行 CSS 的狀態。
如果還不知道面試前端可以問什麼,歡迎參考:
CSS 設計模式
這篇文章將簡單介紹四種 CSS 常見命名原則與設計模式方法論
- BEM: 訂定可以遵循的規範
- OOCSS: 將容器與內容用 “物件” 的概念進行管理
- SMACSS: 依照結構將樣式檔分成五類進行撰寫
- Atomic CSS: 撰寫原子化樣式
無論最終選擇使用哪種方法都將受益於更加結構化的 CSS,風格也更容易被團隊所理解和適應,目標:
- 可預測性 (Predictable)
- 可重複使用性 (Reusable)
- 易維護性 (Maintainable)
- 可擴充性 (Scalable)
減少命名與維護成本
寫樣式檔最大的維護性問題會出現在:
- 多人協作時的命名重複,用 BEM 或是 styled-component 可以去避免
- 陳年專案不確定到底哪些樣式檔還有在使用
針對命名上一般會有三個重點:
- 看到名字就知道效果
- 看到名字就知道用在何處
- 看到名字就可以理解結構上的關係
BEM 命名設計模式
CSS 在相關工具不太普及的時候就出現了 BEM 命名規則:
- 區塊 (Block)
- 元素 (Element)
- 修飾符 (Modifier)
header__title--hover
代表 header 中的 title 在 hover 時的狀態
這樣的命名方法就像是女孩的化妝品們按照分類放進化妝櫃中,透過規範提供了統一又易讀的原則,有原則可預測性就高,就算什麼寫法都不去背誦,也可以透過這樣的原則來理解當時的想法。
透過模組化的概念,樣式不會依賴其他元素,區塊組合的概念也可以重用寫過的樣式。
SMACSS (Scalable and Modular Architecture for CSS)
將樣式檔依照結構上分成五類進行撰寫,分別是 Base、Layout、Module、State、Theme
- Base: 全域設定,未使用 Class 僅設定像 h1~h6、body、a 等等元素,通常可以使用 Normalize 來正規化各瀏覽器預設的樣子,也可以選擇撰寫 Reset CSS 來處理
- Layout: 網頁架構的部分,ex. header、footer、sidebar
- Module: 是獨立且可以重用的元件,舉 bootstrap 的例子
<button type="button" class="btn btn-primary">Primary</button>
,當不需要某個元件時可以安全的移除樣式檔 - State: 元件的狀態,像是被按到的按鈕
- Theme: 設定網站主題,像是暗黑模式
OOCSS (Object Oriented CSS)
主要是兩個概念結構與樣式分離 (Separate structure and skin)、容器與內容分離 (Separate container and content)
- 分離結構與樣式
.btn
: 結構.btn-primary
: 樣式
1 | /* 合併結構與樣式 */ |
- 分離容器與內容,Bootstrap 的格線系統
.col-x
就是用這種方式命名的,容器與內容分離時,容器和內容的重用性就會變高。不過像是 card 跟 card-body 就不需要分離,因為 card-body 獨立也無法使用。
1 | <div class="row"> |
Atomic CSS 設計模式
最近讀了一篇 Facebook 重新設計前端專案的文章,Facebook 是一個功能非常多元的網站,除了動態牆外還涵蓋了社團、粉專、電商平台…等等,所以原來的架構不再適合,因為:
- 對於初次進入網站的使用者來說,大部分的程式碼在剛開始都是不需要被載入的
- 近年需開始實作 dark mode 來提供更好的體驗
原子化樣式是將各種可能的基礎情況都寫成一個 class 然後搭配變數讓整個樣式的撰寫能夠透過組合的方式進行。
缺點在於命名會是一個公版需要大家去習慣,優點是不再需要額外重寫相關的 CSS。
簡化開發流程
原來的開發流程,要處理兩個檔案:
- 寫 HTML tag
- 開 CSS 樣式檔寫樣式
- 把剛寫的 class 塞回 HTML tag
Atomic CSS 的開發流程,只要提早建立原子化樣式像 .mt-3
後續只需要處理一個檔案:
- 寫 HTML 的同時就直接加上
<span class="mt-3">test</span>
為了加速大家開發 Bootstrap 不只定義好了相關元件也提供了過多預設的公版樣式,需要理解後透過覆蓋或是增加權值去修改,感覺有種比誰道行高的感覺。
如果能夠只導入原子化樣式的部分,理論上:
- 簡化開發流程
- 減少命名與維護成本
- 樣式檔的成長也會較接近對數曲線
1 | .m-3 { |
1 |
|
開始使用 Atomic CSS 後我們會發現:
- 因為不用再花心思在命名,像是
form-wrapper
這種命名將不再需要 - 樣式檔的成長速度變成接近對數的曲線
- 可以更快、更小幅度、更安全的修改全站樣式
- 更方便的修改網站主題 (主視覺)
- 移動標記的同時也移動了樣式
導入 Atomic CSS 可能的問題
- 建立時 class 命名一樣需要 convention,需花時間建置符合團隊習慣的命名
- 如果是用 bootstrap 4 需要時間熟悉
- 很特殊的狀況其實還是需要走回 BEM 命名風格去客製化少部分樣式
Utility-First CSS
- Tailwind CSS
- Primer
舉例來說 Primer、Tailwind CSS 主要是縮減大家打字的字數,並且重用基礎的樣式來達到縮減 CSS 體積的效果。
.mt-1: 對應 margin-top: 0.25rem;
.my-2: 對應 margin-top: 0.5rem; margin-bottom: 0.5rem;
1 | .mt-1 { |
喜歡這篇文章,請幫忙拍拍手喔 🤣