BEMについてのまとめ
今回は、BEMとはどんな設計手法なのか?
についてまとめました。
BEM = Block Element Modifierとは
BEMとは、CSSのクラス名を
- どこの (Block)
- なにに (__Element)
- どのように (-Modifier)
つけるかという分類で命名する規則です。
特徴
- MindBEMdingがベース
- csswizardryことHarry Robertsが提唱したCSSの命名規則
- 1つの要素に対して、1つのクラスを指定する
- 構造と見た目を分離して定義するOOCSS(Object Oriented CSS)やAtomic Designとの親和性が高い
BEMのルール
- BlockとElementはアンダースコア2つ(__)で区切る
例) block__element - BlockとModifier, ElementとModifierはハイフン2つ(--)で区切る
例)block--modifier
例)block__element--modifier
// Block = メニュー
<div class="menu">
// Element = ボタン
<div class="menu__item">
// Modifier = 非活性状態
<div class="button--disable"></div>
</div>
</div>
Block
Blockはサイトを構成するパーツ、パーツの親要素です。
例)ボタン、グリッド、タブ、見出し、画像
BEMではBlockを起点とし、Blockを組み合わせることでサイトを構成します。
// DOM
<div class="box">
<a href="/" class="button"></a>
</div>
// ブロック要素で余白を持ったシンプルなBlock
.box {
display: block;
padding: 1em;
}
// ボタンのスタイル
.button {
display: inline-block;
margin: 0;
padding: 0.75em;
border: none;
border-radius: 3px;
color: inherit;
font-family: inherit;
font-size: inherit;
line-height: 1;
text-align: center;
text-decoration: none;
background: transparent;
cursor: pointer;
appearance: none;
&:hover,
&:active,
&:focus {
text-decoration: none;
}
&:disabled,
&.is-disabled {
opacity: 0.5;
pointer-events: none;
}
}
Element
Elementは、Blockを構成するパーツの1つ1つのことを指し、BEMではBlock(親要素)から見て下の階層にいる要素はすべてElement(子孫要素)として扱います。
例)ボタンやコンテンツ部分、見出しや画像
// .boxというBlockのElementとしてボタンを定義
// .box__button-itemは、色やサイズなどの装飾的な指定をする
<div class="box">
<div class="box__button">
<a href="#" class="box__button-item">button</a>
</div>
</div>
Modifier
Modifierは、BlockとElementの状態を変えたいときに指定します。
Modifierは、例えばBlockのスタイルを変更することなく、背景色を変えるなどができるため、構造と見た目を分離でき便利です。
<div class="container container--gray"></div>
// Blockのスタイル
.container {
display: block;
padding: 1em;
}
// 背景色をgrayに変更する
.container--gray {
background-color: gray;
}
BEMの良いところ
- 命名規則が明確
- クラス名を見ただけでどんな要素かが分かりやすい
- 導入コストが低い
- 明確なルールがあるので、一度導入すればコミュニケーションが円滑になる
注意点
BEMでは、BlockにいくつでもElementやModifierを足すことができる一方で、
多用しすぎると可読性が低くなる恐れがあります。
複雑化しやすいパターンとして、
- Element__Element
- Block__Element--Modifier
があります。
Element__Element
このパターンは、多階層のナビゲーションなどBlockから見て、孫要素ができる時に書いてしまいがちです。
<!-- NG -->
// element__elementでマークアップした場合
<ul class="nav">
<li class="nav__item">
<ul class="nav__item__items">
<li class="nav__item__items__item"><a href="#" class="nav__item__items__link"></a></li>
<li class="nav__items__items__item"><a href="#" class="nav__item__items__link"></a></li>
</ul>
</li>
<li class="nav__item">
<ul class="nav__item__items">
<li class="nav__item__items__item"><a href="#" class="nav__item__items__link"></a></li>
<li class="nav__items__items__item"><a href="#" class="nav__item__items__link"></a></li>
</ul>
</li>
</ul>
<!-- Good -->
// Block
<ul class="nav">
// Block__Element
<li class="nav__items">
// Block__Element
<ul class="nav__child-items">
<li class="nav__child-item"><a href="#" class="nav__child-link"></a></li>
<li class="nav__child-item"><a href="#" class="nav__child-link"></a></li>
</ul>
</li>
<li class="nav__items">
<ul class="nav__child-items">
<li class="nav__child-item"><a href="#" class="nav__child-link"></a></li>
<li class="nav__child-item"><a href="#" class="nav__child-link"></a></li>
</ul>
</li>
</ul>
Block__Element--Modifier
以下のように、ElementにModifierを指定すると、冗長になります。
基本的に、Block--Modiferを起点にしてスタイルを指定すると見やすくなります。
<!-- NG -->
<div class="box">
<div class="box__element box__element--pad-large"></div>
<div class="box__element box__element--pad-large"></div>
</div>
.box__element {
padding: 1em;
}
// Elementのpaddingを変更するModifier
.box__element--pad-large {
padding: 2em;
}
<!-- Good -->
<div class="box box--pad-large">
<div class="box__element"></div>
<div class="box__element"></div>
</div>
.box__element {
padding: 1em;
}
.box--pad-large > .box__element {
padding: 2em;
}
ディレクトリでCSSを管理する方法
SMACSS, Scalable and Modular Architecture for CSS
CSSを以下5つに分類し、各ディレクトリにファイルを保存します。
共通化ができるので、再利用性が高いのと、ディレクトリごとに分けてるので見やすく、管理しやすいのが特徴です。
- Base:サイト全体に影響するもの(リセットCSSや変数の定義など)
- Layout:ページのレイアウト(ヘッダー、フッターなど)
- Module:再利用可能なパーツのこと(繰り返し使うボタンなど)
- State:状態によって見た目が変化するもの(色の変化など)
- Theme:テーマごとのスタイルのこと(サイトをダークモードにガラッと変えるなど) |
その他
- 「1ページに1度しか登場しないレイアウト」についてはIDセレクタが容認される
- LayoutカテゴリやStateカテゴリにあたるクラスには、接頭辞をつけることが推奨されている
FLOCSS, Foundation Layout Object CSS
FLOCSSは、SMACSSのようにモジュールを切り分けられるなど、他の有名なCSS設計を上手く取り入れて設計されています。
フォルダ構成例
- Foundation:デフォルトスタイル
- reset.css
- variable.css etc.
- Layout:各ページを構成するサイト全体で共通したエリア
- l-hader
- l-footer etc.
- Object:サイト全体で再利用できるパターンを持つモジュール
- Component:小さな単位のモジュール
- c-button.css
- c-grid.css etc.
- Project:いくつかの↑Componentと、他の要素によって構成される大きな単位のモジュール
- p-list.scss
- p-card.scss
- Utility:ComponentとProjectのモディファイア(パターン)で解決することができないスタイル、また、調整のための便利クラスなど
- u-margin.css
- u-padding.css
- Component:小さな単位のモジュール
参考
BEM(MindBEMding)によるCSS設計
BEM(MindBEMding)についてややこしくない説明をしてみた
BEMとは何か
CSSの設計(OOCSS, BEM, SMACSS, FLOCSS)
FLOCSSのまとめ
Discussion