BEM、SMACSS、OOCSS — CSS 三種常見命名原則

Chih Yu Kao
5 min readOct 10, 2021

--

會想寫這篇是因為最近在改寫專案的前端介面,原以為自己對於命名的部分還算有些認知,但在改專案的過程中發現頁面超級無敵多,做到後來就漸漸意識到自己對於 class 命名的原則並沒有掌握得很好,因此想寫這篇來稍微整理一下自己對於命名的理解

freeCodeCamp 上針對 class 命名的三個重點:

To know what a selector does, just by looking at its name

To have an idea of where a selector can be used, just by looking at it

To know the relationships between class names, just by looking at them

翻譯成中文是 (PS.非專業翻譯)

  1. 看到名字就知道是做甚麼的
  2. 看到名字就知道這個可以用在哪
  3. 看到名字就可以知道跟其他 class 之間的關係

從這三項可以知道 class 命名的重點在於是否能看到就能直覺地知道這個 class 的用法

下面整理幾個一般常見的命名方式,分別是 BEM、SMACSS、OOCSS

BEM

  • B:Block 區塊
  • E:Element 元素
  • M:Modifier 修飾子

[Block]__[Element] — [Modifier] (區塊__元素 — 修飾子)

舉例來說,如下圖:

BEM 命名範例
  • card__title — big 卡片(區塊)__標題(元素) — 大(修飾子)
  • card__title — small 卡片(區塊)__標題(元素) — 小(修飾子)

這樣的命名就可以清楚知道是哪一個部份的甚麼元素,加上修飾子就可以針對一些樣式進行調整,而不用重複去寫 css

SMACSS

全名是 Scalable and Modular Architecture for CSS,分成五個類別進行命名,其分類的結構分別是Base、Layout、Module、State、Theme

  • Base:css 基本的部分,還未加上 class 名稱的原始元素,ex. h1~h6, body, a… 一些元素初始的設定
  • Layout:網頁架構的部分,ex. header、footer、sidebar
  • Module:屬於元件,ex. button
  • State:元件的狀態 ex. .button .focus,被按到的按鈕, 這樣是一種狀態
  • Theme:顏色或大小等可以多變但同類的屬性 button — dark,也可以接個 light

把 class 依照這樣個別區分去命名,避免 class 過於肥大而且也可以方便擴張

ex. 寫一個 button class .btn 這個是原始型的 button, 顏色、大小則可以另外寫一個 class,這樣不但重複使用性高也可以更方便的進行排列組合

SMACSS 命名範例
SMACSS 命名範例
  • btn 按鈕的基本架構 , 可能包含如 text-alignpadding
  • btn-dark、btn-light 按鈕的顏色如 colorbackground-color
  • btn-sm 按鈕的尺寸大小如 widthheightfont-size

這個方法雖然方便排列組合, 但有個缺點是分類結構的定義其實會有些模糊的界線

OOCSS

全名是 Object Oriented CSS,他的命名跟 SMACSS 有些類似,但他分類的定義相對來說比 SMACSS 的更廣

分類重點有兩個:

  • 分離結構與樣式
  • 分離容器與內容

分離結構與樣式,不幫 HTML tag 直接寫 css,而是另寫一個 class
ex. content 裡面有一個 span 包住的樣式想讓它是紅色,直接如下面範例寫的話,當之後想要有其他顏色時就無法適用。

.content > span {  
color: red;
}

改成直接幫 span 命名,再把 class 加在 <span></span> ,這樣之後想要有其他顏色,也可以更好擴張應用

.span-red {  
color: red;
}

分離容器與內容,把包住內容的外層 tag 跟裡面的內容的元素分開命名
ex. 想讓內容的區塊可以 space between 排列,就幫外層容器寫一個 space between 的樣式,這樣其他地方也需要這個排列方式就可以直接拿來用。

.container-spacebetween {  
display: flex;
justify-content: space-between;
}

PS. 有名的 Bootstrap也是使用這種方式進行命名,也可以參考裡面範例來去更了解 OOCSS 的命名原則

最後彙整一下前面介紹的三個命名方式

BEM、SMACSS、OOCSS 三種命名方式彙整

結論是不管使用哪種方式,命名要點其實都是差不多的,主要有以下四點:

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

這篇介紹主要只是理論的部分,理解上來說其實並不困難,但自己在開發時,即便知道那些要點,也常常有許多需要掙扎跟思考的部分。雖然自己在 class 命名的部分還有很多待加強的部分,但當開發過程中發現有些命名的 class 其實還不錯用時,心理也是一個順暢啊!

--

--