概要
中~大規模なWebサイトを効率的に開発・運用していくには、同じ役割を持つ部品を共通化して、どこでも再利用できる部品=コンポーネント化することが重要。BEMはそのようなコンポーネント設計をCSSで管理・運用しやすくすることを目的として開発された手法で、どの規模のサイトであっても汎用的に使える設計ではあるが、特に中~大規模なWebサイト構築に向いている手法であると言える。
Block、Element、Modifier
- block(ブロック)
それ単体で独立した1つのコンポーネントとなるものをBEMでは「Block」と呼ぶ。Blockには他と被らない、その部品の役割がひと目で分かる名前を付けておく必要がある。そうすることによってどこでも再利用できるコンポーネントとしての役割を担保している。また、Blockの中に別のBlockを含めることができる。 - Element(エレメント)
Elementは特別の親Blockの中でのみ使用できる部品であり、Element単体では使用できない。命名には必ずそのElementが所属する親Blockの名前を付け、「Block__Element」のようにアンダースコア2つで構造化することで、どのBlockに所属する部品なのかがひと目で分かるようにする。 - Modifier(モディファイア)
Modifierは色違いのようなちょっとしたスタイルのバリエーションや、選択されている、開いている、といったコンポーネントの状態を表現したい場合に使う。Modifier用の名前は、「Block–Modifier」「Block__Element–Modifier」のようにハイフン2つで構造化する。
命名規則とその応用①
BEMは命名規則によってそのスタイルの仕様場所や用途が分かるようにするため、記号の使い方に特徴がある。この区切り記号のことを「セパレーター」と呼ぶ。
BlockとElementをつなぐセパレーターはアンダースコア2つ(__)。これは、ElementがBlockの下に所属するものであることを示している。
これに対してBlockやElementとModifierをつなぐセパレーターはハイフン2つ(–)。これはModifierがBlockやElementと並列のバリエーション違いであることを示している。
また、区切り記号が2つ重ねてあるのは、Block、Element、Modifierなどの名前に2つ以上の単語を使用する場合には、ハイフン1つでつなげるケバブケースという命名規則を採用するのが一般的であるため、これと明確に区別する目的がある。
命名規則とその応用②
細かい記法のルールについては基本的なBEMの構造さえ守られていればある程度アレンジすることも可能。
- 複数単語を使う場合、ローワーキャメルケースを採用する(単語同士を連結して2つめ以降の単語の先頭文字だけ大文字とする)
- ローワーキャメルケース採用を前提として、Element、Modifierのセパレーターを2つではなく1つに減らす
といった事例は時々見かけることがある。
/* 本来のBEM記法 */
.global-nav {...}
.global-nav__list {...}
.global-nav__item {...}
.global-nav__item--current {...}
/* アレンジしたBEM記法 */
.globalNav {...}
.globalNav_list {...}
.globalNav_item {...}
.globalNav_item-current {...}
BEMのデメリット
BEMの気持ち悪さの原因は「class名が長すぎる」という点がある。Block__Element–Modifierと構造を全てつなげて明記するのが基本なので、ただでさえ1つのclass名が長くなるのに、特にModifierが複数重なった時は正直げんなりするほど冗長なマークアップになってしまう。