[Note] 模組化 CSS(Modularity CSS)
keywords: modularity
, 模組化
, OOCSS
統整不同設計模式
模組化的 CSS 通常包含這幾個部分:
- Module:又稱作 object, block , component,是可以重複使用、自我獨立的樣式,像是 media object, navigation, page header。
- Child Element:一個具體可切分的模組,不能獨立存在,例如 media object image, navigation tab, page header logo。
- Module Modifier:又稱作 skin 或 theme,用來改變 module 的外觀,例如 left/right media objects, vertical/horizontal navigation。
模組化的 CSS 通常可以分成這幾個類別:
- Base:HTML 元素的預設樣式,例如
a
,li
,h1
。 - Layout:控制 module 如何被排版,但不是視覺上的外觀,例如
.l-centered
,.l-grid
,.l-fixed-top
。 - Modules :視覺上可以重複使用、獨立的 UI 元件,例如
.m-profile
,.m-card
,.m-modal
。 - State:通常透過 JavaScript 來新增或移除,例如
.is-hidden
,.is-collapsed
,.is-active
- Helper:又稱為 utility,獨立於 module,小小易用的樣式,例如
.h-uppercase
,.h-nowrap
,.h-muted
。
模組化的 CSS 通常建議:
- 不要使用 IDs
- 不要嵌套超過一層以上
- 為 child element 添加 class
- 跟隨命名規則
- 使用前綴命名 class
常見的 CSS 模組化設計模式
以下說明幾種常見的模組化 CSS 慣例/設計模式:
OOCSS
在 OOCSS 中,物件(object)指稱的是一個區塊(block)或元件;而皮膚/主題(skinned / themed)指稱的是修飾符(modifier)。
Context Independent:將元件從脈絡中獨立出來
一個 object 不論你放在哪裡,都應該要看起來一樣,而不會隨著它的脈絡(context)而變。
舉例來說,當導覽列的按鈕是藍色,而內文的按鈕是綠色時,你不應該在導覽列或內文中定義該按鈕顏色,而是把按鈕的顏色抽出成一個獨立的 class,稱作 modifier,如此它們將可以在其他地方被覆用,而不會只被限定在某個區塊。
Skinning (aka Theming)
將 object 的結構從樣式中抽離出來,每一個元件不論它的外觀為何,都應該有相同的 HTML 結構。
Use Classes:不同的 HTML 結構可以套用相同的樣式。
使用 class 來為 object 和他們的子元素命名,因此即使 HTML 的結構改變了,也不會影響到樣式。
舉例來說,我們透過當我們以 class 來命名標題的樣式時,.headline
,如此當你的結構從 <h1>
換成 <h4>
時一樣可以有同樣的外觀,因此不建議寫 h1 {...}
,因為結構一但改變,樣式就無法套用了。
不要使用 ID
過去會使用 ID 來當作命名空間(namespace),如此可以指稱到該 ID 內的元素。但由於模組化 CSS 中強調的是重複使用,因此使用 ID 意味著你的這個物件是無法被覆用的。
BEM - Block, Element, Modifier
區塊(Block)
Block 指的是可以透過邏輯或功能從頁面中獨立出來的元件。
首先,block 是可以嵌套在另一個 block 中的(nestable),它們可以被包含在其他的 block 中而不會壞掉。例如,當我們把按鈕放在導覽列中時,按鈕的樣式並不會因此而壞掉。
接著,block 是可以被重複使用的(repeatable)。
元素(Element)
Element 是組成 block 的部分,但是它不能在 block 的外部被使用。例如導覽列選單(navigation menu)中的選項(item)。
修飾符(Modifier)
Modifier 用來定義某一 block 的外觀和行為。例如選單 block 可能會根據 modifier 的不同而從水平變成垂直。
不要使用嵌套式的 CSS 選擇器
在 BEM 中不建議使用嵌套式的 CSS 選擇器 .btn .btn-price
這種用法(如果可以不用就不要用),因為這會使得它們的權重增加,使得它們變得較難覆用,因此應該要寫成 .btn__price
就好。
但有一個例外是,當根據 modifiers 用來修改某 element 或 block 的樣式時,可以使用 .btn__text .btn--orange
。
命名規則(Naming Convention)
.block-name__element--modifier
block-name
會用小寫block-name
裡面如果有多個單字,用-
區隔
SMACSS
SMACSS 中最重要的是**分類(Categorization)**的概念,他認爲在 CSS 系統中會包含這幾種類別:
- Base:指的是 HTML 元素的預設樣式,像是
links
,paragraph
,headlines
。 - Layout:將頁面切分成區塊(section),並包含一個以上的模組(module)。
- Module:又稱作 object 或 block,是可以重複使用、模組化的設計,例如
button
,media object
,product list
等等。 - State:用來描述 module 或 layout 看起來的狀態,通常會透過 JavaScript 來增添,例如
hidden
,expanded
,active
。 - Theme:描述當一個 theme 套用之後,module 或 layout 會變成什麼樣子。
命名原則
l-
的前綴用來描述 layout :l-inline
m-
的前綴用來描述 module:m-callout
is-
的前綴用來描述 state:is-collapsed