淺談 CSS 設計模式系列-BEM 篇

前言

BEM 是一個為了讓 className 有更好地維護架構 CSS 設計模式,但最主要的致命缺點就是命名長度過長,可是在實際開發上非常多人都會使用到 BEM。

BEM

BEM 其實是三個單字的縮寫

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

在 BEM 的設計模式下,每一個都是元件的概念去開發,舉例來講底下的 HTML 結構我們無法得知彼此之間的相依性

1
2
3
4
5
6
<header class="header">
<ul class="main">
<li class="item"></li>
<li class="item active"></li>
</ul>
</header>

我們無法得知 .main.item 是否只存在於 header 並且有可能其他地方會使用到 .main.item 的名稱,那麼就會發生衝突,因此 BEM 的設計模式就會顯得非常易讀且確保相依性。

Block (區塊)

Block 簡單來講在上述範例中第一層 class="header" 就是屬於一個 Block,簡單來講每一個 Block 都是獨立存在的個體,並且有可以重複使用的元件,例如

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<header class="header">
<ul class="main">
<li class="item"></li>
<li class="item"></li>
</ul>
</header>
<section class="cart">
<ul class="main">
<li class="item"></li>
<li class="item"></li>
</ul>
</section>
<section class="order">
<ul class="main">
<li class="item"></li>
<li class="item"></li>
</ul>
</section>

在上述範例中就有三個 Block 分別為 .header.cart.order

當然 BEM 的設計原則是為了讓 class 更好,因此也會有可能出現 prefix(前綴詞)變成 .b-header.b-cart.b-order

Element (元素)

Element 則是 Block 的子元件(兒子概念),並且他無法獨立於 Block 之外,但有些 Block 可能會沒有 Element。

因此在上面的範例中,我們可以將 .mainitem 改為以下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<header class="header">
<ul class="header__main">
<li class="header__main__item"></li>
<li class="header__main__item"></li>
</ul>
</header>
<section class="cart">
<ul class="cart__main">
<li class="cart__main__item"></li>
<li class="cart__main__item"></li>
</ul>
</section>
<section class="order">
<ul class="order__main">
<li class="order__main__item"></li>
<li class="order__main__item"></li>
</ul>
</section>

Element 的標示方式是兩個下底線「__」,主要是第一個為 block 然後使用「__」當作前綴詞表示接下來的是 Element,因此你有可能看到非常長的 Element。

Modifier (修飾符)

Modifier 簡單來講就是狀態的意思,主要是使用 「--」 去代表 Modifier,舉例來講在上述範例中如果 li 有一個選取的狀態 .active 那麼 BEM 會如何表示?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<header class="header">
<ul class="header__main">
<li class="header__main__item header__main__item--active"></li>
<li class="header__main__item"></li>
</ul>
</header>
<section class="cart">
<ul class="cart__main">
<li class="cart__main__item"></li>
<li class="cart__main__item cart__main__item--active"></li>
</ul>
</section>
<section class="order">
<ul class="order__main">
<li class="order__main__item order__main__item--active"></li>
<li class="order__main__item"></li>
</ul>
</section>

甚至在 Modifier 下是允許有多個狀態的

1
2
3
4
5
6
<section class="order">
<ul class="order__main">
<li class="order__main__item order__main__item--active order__main__item--danger"></li>
<li class="order__main__item"></li>
</ul>
</section>

最後直得一提的是,早期的 BEM Modifier 其實是一個「_

1
2
3
4
5
6
<section class="order">
<ul class="order__main">
<li class="order__main__item order__main__item_active order__main__item_danger"></li>
<li class="order__main__item"></li>
</ul>
</section>

是後來發現這樣子的可讀性較低,因此才改了雙「--」,所以其實我們現階段所使用的 BEM 都是改良過得 BEM 設計模式。

參考文獻

0%