5分で理解するBEM
この記事は
フロントエンド初心者が、「BEMって何?」と思ったときにさっと概観を理解でき、BEMに従って簡単なマークアップをできるようになることを目指したもの。
BEMとは?
CSSの設計手法の1つ。
他に有名なCSS設計手法として、OOCSS、SMACSS、FLOCCSなどがある。
B(Block)、E(Element)、M(Modifier)の略である。
サンプルコード
<!-- block -->
<div class="header">
<!-- block -->
<div class="logo"></div>
<!-- block -->
<form class="search-form search-form_focused">
<div lass="search-form__content">
<!-- element -->
<div class="search-form__label">
<!-- block -->
<div class="search-label-text">検索</div>
<!-- block -->
<div class="search-label-icon"></div>
</div>
<!-- element -->
<input class="search-form__input">
<!-- element -->
<button class="search-form__button search-form__button_size_m"></button>
</div>
</form>
</div>
Block、Element、Modifierそれぞれの説明
Blockとは
A functionally independent page component that can be reused. In HTML, blocks are represented by the class attribute.
機能的に独立しており、あらゆる場所で再利用ができるパーツのこと。
これを実現するため、例えばBlockにはそれ自体の位置を決めるようなCSSを書くべきではない。
Elementとは
A composite part of a block that can't be used separately from it.
Blockを構成するパーツのこと。
クラス名には必ずBlock名を入れ、Block名__Element名
のような形式にすること。
Elementは必須ではないので、Blockの下にElementを置かないのもOK(例:サンプルコードのlogo)
Modifierとは
An entity that defines the appearance, state, or behavior of a block or element.
BlockやElementの見た目や状態や振る舞いを定義するもの。
1つのBlockやElementに対し、複数のModifierをつけることができる。
命名の仕方には2パターンある。
クラス名(Boolean)
クラス名は、
-
Block名_Modifier名
(Blockの場合) -
Block名__Element名_Modifier名
(Elementの場合)
のような形式にすること。(例:サンプルコードのsearch-form_focused
)
クラス名(Key-value)
「ある項目が」(Key)「ある値で」(Value)あるModifierという名前づけができる。(例:サンプルコードのsearch-form__button_size_m
は、size
がKey、m
がValue。中サイズのボタンのスタイル指定となっている。)
クラス名は、KeyとValueをアンダースコア区切りにする。
-
Block名_Modifier(Key)_Modifier(Value)
(Blockの場合) -
Block名__Element名_Modifier(Key)_Modifier(Value)
(Elementの場合)
のような形式にすること。
Block、Elementのスタイルを組み合わせる「Mix」
A technique for using different BEM entities on a single DOM node.
単一のDOMノードに、複数のBEMエンティティを適用すること。
今まで見てきた例では、1つのHTMLタグはBlockかElementどちらかの1つの役割になっていたが、例えば以下のようにBlock(search-form
)でもありElement(header__search-form
)でもあるという状態にすることができる。
<!-- `header` block -->
<div class="header">
<!--
The `search-form` block is mixed with the `search-form` element
from the `header` block
-->
<div class="search-form header__search-form"></div>
</div>
これにより、「Blockとして指定したいスタイル」「Elementとして指定したいスタイル」がそれぞれある場合に分離して書いた上で組み合わせて適用ができるので再利用性が高まる。
他の場所でも再利用できるようなformというパーツそのもののスタイル定義はBlock(search-form
)に、位置合わせなど配置される場所に依存するスタイル定義はElement(header__search-form
)として記述するとよい。
.search-form {
border: 1px solid black;
padding: 10px;
}
.header__search-form {
margin-top: 30px;
}
なお、今回はBlockが1つ・Elementが1つとなっているが、複数指定することも可能。
File Structure
BEMはHTMLやCSSの構成だけでなく、ファイルの分割方法についても規則がある。
- 1 Blockあたり1ディレクトリ。配下にElementとModifierを定義したディレクトリを配置
- Block名とディレクトリ名は同じにする
- Elementのディレクトリ名は
__
から始まる - Modifierのディレクトリ名は
_
から始まる
補足
ネストについて
-
Blockの中に別のBlockを置くことはOK
- サンプルコードでの
header
とlogo
のような感じ
- サンプルコードでの
-
Elementの中に別のElementを置くこともOKだが、名前に気をつけること
- サンプルコードの
search-form__content
、search-form__input
のような感じ - 必ず、名前によりどこのBlockに含まれるものかを明確化する
- サンプルコードの
-
Elementの中に別のBlockを置くこともOKだが、こちらも名前に気をつけること
- サンプルコードの
search-form__label
、search-label-text
、search-label-icon
のような感じ - 中のBlockは親のElement名は引き継がない
- サンプルコードの
-
上位BlockのないElementはNG
- CSSのスコープを限定するために重要な規則
BlockとElementの使い分けは?
何らかのパーツの下でのみ使われるパーツは、Elementにすべき。サンプルコードのsearch-formの下のElementがわかりやすい。
逆に、他の箇所でも使えるパーツはBlockにするとよい。
なんとなくBlockの中にElementというイメージで、Blockが大きなパーツでなくてはいけない気もしてくるが、独立していて・いろいろな箇所で再利用かどうかがBlockにするかどうかのポイント。
更に詳しく
-
公式ドキュメント
- この記事で紹介した以外にもいろいろな命名の派生系がある:https://en.bem.info/methodology/naming-convention/
- 個人的にはModifierが
_
から始まるのが見にくいので、--
でつけていくほうが好きです
- 個人的にはModifierが
- 実際に書いていて困ったことがでてきたら役に立ちそう
- この記事で紹介した以外にもいろいろな命名の派生系がある:https://en.bem.info/methodology/naming-convention/
- CSS設計全体についてはこちらの書籍が良いです:CSS設計完全ガイド ~詳細解説+実践的モジュール集
Discussion