BEM、SMACSS、OOCSS — CSS 三種常見命名原則
會想寫這篇是因為最近在改寫專案的前端介面,原以為自己對於命名的部分還算有些認知,但在改專案的過程中發現頁面超級無敵多,做到後來就漸漸意識到自己對於 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.非專業翻譯)
- 看到名字就知道是做甚麼的
- 看到名字就知道這個可以用在哪
- 看到名字就可以知道跟其他 class 之間的關係
從這三項可以知道 class 命名的重點在於是否能看到就能直覺地知道這個 class 的用法
下面整理幾個一般常見的命名方式,分別是 BEM、SMACSS、OOCSS
BEM
- B:Block 區塊
- E:Element 元素
- M:Modifier 修飾子
[Block]__[Element] — [Modifier] (區塊__元素 — 修飾子)
舉例來說,如下圖:
- 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,這樣不但重複使用性高也可以更方便的進行排列組合
- btn 按鈕的基本架構 , 可能包含如
text-align
、padding
- btn-dark、btn-light 按鈕的顏色如
color
、background-color
- btn-sm 按鈕的尺寸大小如
width
、height
、font-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 的命名原則
最後彙整一下前面介紹的三個命名方式
結論是不管使用哪種方式,命名要點其實都是差不多的,主要有以下四點:
- 可預測性( Predictable )
- 可重複使用性( Reusable )
- 易維護性( Maintainable )
- 可擴充性( Scalable )
這篇介紹主要只是理論的部分,理解上來說其實並不困難,但自己在開發時,即便知道那些要點,也常常有許多需要掙扎跟思考的部分。雖然自己在 class 命名的部分還有很多待加強的部分,但當開發過程中發現有些命名的 class 其實還不錯用時,心理也是一個順暢啊!