BEM で CSS の要素を命名する


はじめに

インターン先が BEM という CSS の命名規則を採用していた。
良い機会なので、ドキュメントを読んで自分なりにまとめてみる。

BEM とは

Block、Element、Modifier の頭文字をとった、コンポーネントベースの CSS記述手法。
UI を独立したブロックに分割することで、複雑なデザインの実装やコードの再利用を容易にしている。
また、タグに直接 CSS を記述したり、idを与えたりすることは非推奨とされる。

Block と Element

BEM において各要素は、大きく BlockElement の 2種類に分けられる。
名前は classname 属性で与えられ、redbigなど特徴を説明する単語ではなく、formerrorなど役割を表すものでなければならない。

Block

他要素の影響を受けない独立した要素で、それ自体を使い回すことができる。
周囲に影響を与えてはならず、marginpositionは指定しない。
子要素に Element を持ち得る。
Block の名前は、属する Element に対して名前空間を定義する。

Element

親要素(Block)がなければ使うことができない要素で、Block の一部。
Element どうしのネストも可能だが、あくまで属する先は Block である。
Block 無しで、いきなり Element を記述することはできない。

例えばwidth: 100%;というスタイルがあたっている場合、横幅は親要素の横幅に依存するため、この要素は Element となる。

どうしても Block 内を細かく分けたい場合は、Service Block と呼ばれる要素を用いるらしい。

Modifier

上で書いた通り、BlockElement の名前は役割を表す言葉でなければならない。
これに対し、大きさや状態等を表す名前を持つのが Modifier である。
主に以下の 2パターンに当てはまった名前を持つ。

真偽値

truefalseで答えられるような状態を表す単語。
disablevisibleなど。

キーバリュー

ある key と、それに対する value の2単語をアンダースコアで繋いだ文字列。
size_scolor_blackなど。

Modifier を含んだクラス名を単体で使うことはできず、必ずメインの BlockElement 名と併せて定義する。

ある一つの要素に対し、色違いや状態違いなどを定義するときに使う。

<div class="button">
    メインのボタン
</div>
<div class="button button_focused">
    フォーカス時のボタン
</div>
<div class="button button_color_red">
    メインのボタンの赤色バージョン
</div>

クラス名の付け方

Block 名と Element 名の間は__(アンダースコア 2つ)で、Block / Element 名と Modifier の間は_(アンダースコア 1つ)で繋げる。
Block / Element / Modifier それぞれが 2単語以上になる場合、単語間は-(ハイフン 1つ)で区切る。

<div class="list">
    <div class="list__item list__item_color-primary">
        要素1
    </div>
    <div class="list__item list__item_color-secondary">
        要素2
    </div>
</div>

Modifier の前の_--(アンダースコア 2つ)とする場合や、Block 名をアッパーキャメルケースにする場合もあるっぽい。

Mix

ある要素について、Block 属性と Element 属性を同時に与える技術。

例えば単体で使い回すことができるコンポーネントを、ある親要素の中にmarginを指定して配置したいときなどに用いる。

<div class="carousel">
    <div class="card carousel__card">
        カルーセル内に配置したカード
    </div>
</div>
<div class="card">
    カード単体でも使える
</div>

おわりに

まだ分かりきっていない部分もあるので、理解が進んだら適宜追記する。

参考