iT邦幫忙

2022 iThome 鐵人賽

DAY 4
0
Modern Web

前端三分鐘 X 從把妹角度理解前後端如何和平相處系列 第 4

透過 BEM、SMACSS、OOCSS、Atomic CSS 簡化樣式開發流程、減少維護成本 (4)

  • 分享至 

  • xImage
  •  

本篇文章將提到怎麼透過 BEM、SMACSS、OOCSS、Atomic CSS 的特性來:

  • 縮短開發時間
  • 減少需維護的程式碼
  • 結構與樣式

CSS 選擇器和規則們就像女孩化妝桌上的化妝品們,桌上總是放著各個種類,數也數不清大罐小罐擠的噴的擦的,在沒有預備知識和整理規劃的情況下,若要一個男孩子短時間搞清楚簡直是天方夜譚。

當交接新專案的時候看到幾千行的樣式檔大概也是這樣的心情,一般專案在未規範的情況下,通常都會發展為幾千甚至幾萬行 CSS 的狀態。

如果還不知道面試前端可以問什麼,歡迎參考:

CSS 設計模式

這篇文章將簡單介紹四種 CSS 常見命名原則與設計模式方法論

  • BEM: 訂定可以遵循的規範
  • OOCSS: 將容器與內容用 "物件" 的概念進行管理
  • SMACSS: 依照結構將樣式檔分成五類進行撰寫
  • Atomic CSS: 撰寫原子化樣式

無論最終選擇使用哪種方法都將受益於更加結構化的 CSS,風格也更容易被團隊所理解和適應,目標:

  1. 可預測性 (Predictable)
  2. 可重複使用性 (Reusable)
  3. 易維護性 (Maintainable)
  4. 可擴充性 (Scalable)

減少命名與維護成本

寫樣式檔最大的維護性問題會出現在:

  • 多人協作時的命名重複,用 BEM 或是 styled-component 可以去避免
  • 陳年專案不確定到底哪些樣式檔還有在使用

針對命名上一般會有三個重點:

  1. 看到名字就知道效果
  2. 看到名字就知道用在何處
  3. 看到名字就可以理解結構上的關係

BEM 命名設計模式

CSS 在相關工具不太普及的時候就出現了 BEM 命名規則:

  • 區塊 (Block)
  • 元素 (Element)
  • 修飾符 (Modifier)

header__title--hover 代表 header 中的 title 在 hover 時的狀態

這樣的命名方法就像是女孩的化妝品們按照分類放進化妝櫃中,透過規範提供了統一又易讀的原則,有原則可預測性就高,就算什麼寫法都不去背誦,也可以透過這樣的原則來理解當時的想法。

透過模組化的概念,樣式不會依賴其他元素,區塊組合的概念也可以重用寫過的樣式。

SMACSS (Scalable and Modular Architecture for CSS)

將樣式檔依照結構上分成五類進行撰寫,分別是 Base、Layout、Module、State、Theme

  1. Base: 全域設定,未使用 Class 僅設定像 h1~h6、body、a 等等元素,通常可以使用 Normalize 來正規化各瀏覽器預設的樣子,也可以選擇撰寫 Reset CSS 來處理
  2. Layout: 網頁架構的部分,ex. header、footer、sidebar
  3. Module: 是獨立且可以重用的元件,舉 bootstrap 的例子 <button type="button" class="btn btn-primary">Primary</button>,當不需要某個元件時可以安全的移除樣式檔
  4. State: 元件的狀態,像是被按到的按鈕
  5. Theme: 設定網站主題,像是暗黑模式

OOCSS (Object Oriented CSS)

主要是兩個概念結構與樣式分離 (Separate structure and skin)、容器與內容分離 (Separate container and content)

  1. 分離結構與樣式

.btn: 結構
.btn-primary: 樣式

/* 合併結構與樣式 */
.login-button {
  color: blue;
  padding: 10px 20px;
}

/* 結構與樣式分離 */
.btn {
  padding: 10px 20px;
}
.button-primary {
  color: blue;
}
  1. 分離容器與內容,Bootstrap 的格線系統 .col-x 就是用這種方式命名的,容器與內容分離時,容器和內容的重用性就會變高。不過像是 card 跟 card-body 就不需要分離,因為 card-body 獨立也無法使用。
<div class="row">
  <div class="col-12">
    <div class="content"></div>
  </div>
</div>

<!-- 不須分離 -->
<div class="card">
  <div class="card-body"></div>
</div>

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. 簡化開發流程
  2. 減少命名與維護成本
  3. 樣式檔的成長也會較接近對數曲線
.m-3 {
  margin: 1rem !important;
}

.mt-3,
.my-3 {
  margin-top: 1rem !important;
}

.mr-3,
.mx-3 {
  margin-right: 1rem !important;
}

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.4.0/css/bootstrap.min.css" />
  <style>
    .form-wrapper {
      padding: 1rem;
      margin: 0.25rem;
      background-color: #007bff;
    }
    .form__input {
      margin: 1rem;
    }
  </style>
</head>
<body>
  <form class="form-wrapper">
    <input class="form__input"></input>
  </form>
  <!-- Atomic CSS -->
  <form class="p-3 bg-primary m-1">
    <input class="m-3"></input>
  </form>
</body>
</html>

開始使用 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;

.mt-1 {
  margin-top: 0.25rem;
}

上一篇
CSS 易容術入門 (3)
下一篇
解密 CSS 處理器 SCSS/PostCSS (5)
系列文
前端三分鐘 X 從把妹角度理解前後端如何和平相處30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
Oo_花之舞__oO
iT邦新手 1 級 ‧ 2023-04-08 16:03:42

神等文章 每篇都超級清楚 架構也很好

感謝大大誇獎,不介意的歡迎到我的粉絲專頁按個讚 (雖然很少發文XD
https://www.facebook.com/linyencheng.tw

我要留言

立即登入留言