class名の命名規則BEMのルールとカスタマイズ
よく使われるclass名の命名規則
HTMLにclass名をつける時の代表的な命名規則には以下の3つがあります。今回はこの中のBEMについて紹介します。
- BEM(Block-Element-Modifier:ベム)
- OOCSS(Object Oriented CSS:オーオーシーエスエス)
- SMACSS(Scalable and Modular Architecture for CSS:スマックス)
BEMとは
BEM(ベム)はHTML要素を「Block」「Element」「Modifier」に分けてclass名をつけます。この3つの頭文字を使って「BEM」と呼びます。
BEMのメリット
- パーツ単位でデザインを管理する為、変更時に他のパーツへの影響を考慮しなくていい
- セレクタを入れ子にしないので優先度問題が発生しにくい
- BEMを採用している会社が多い
BEMのデメリット
- class名が長い
- すべての要素にclass名を付与するのでHTMLが読みづらくなる
- Bootstrapとの相性が悪い(BootstrapはOOCSSを採用している)
HTML要素をパーツ単位で管理:Block
BEMではHTML要素をパーツ単位で管理します。このパーツを「Block」として扱います。以下のワイヤーフレームをパーツ単位でBlock作成してみます。
Blockのルール
- パーツとして独立完結しており別場所に移動しても機能する
- Block内にBlockが入れ子になってもOK
※ただしスタイルはBlock単位で記述し、複数のBlockをまたいでの子孫セレクタを使用しない
「ヘッダーパーツ」「アイキャッチパーツ」「紹介パーツ」で構成されています。
「ヘッダーパーツ」内には「ロゴパーツ」「ヘッダーナビパーツ」「お問い合わせパーツ」。「紹介パーツ」内には「紹介項目パーツ」が入れ子になっています。
赤枠で囲ったこれらのパーツが「Block」と考えることができます。
パーツ内の部品:Element
パーツ(Block)内の部品を「Element」として扱います。緑枠がElementになります。
Elementのルール
- 必ずBlock内にある
- 同じElementが複数存在してもOK
- Element内にElementが入れ子になってもOK
※入れ子が深くなる時はElement内でBlockを作成できないか検討する
パーツのバリエーション(状態):Modifier
パーツ構成は一緒だが「見た目」や「動き」の違うパーツを作成する際にModifierを使用します。
以下の例の場合、紫枠パーツが他のパーツと構成は一緒だが「マーカー(行頭記号)」が「○」と「■」で違っています。この場合は既存のBlockやElementに「Modifier」を付与してデザインを定義します。
Modifierのルール
- 既存のBlockもしくはElementに付与する
- 1つのパーツに複数Modifierを付与してもOK
BEMの命名規則
Block
class名は必ずBlock名から開始します。
<div class="Block名">
</div>
例えば上記のロゴの場合はこのように命名します。
<div class="logo">
</div>
Element
ElementはBlock名の後に「_(アンダースコア)」を2つでつなぎます。この「_(アンダースコア)」2つを「セパレーター」や「区切り文字」と呼び、後述のModifierの区切りや名前の区切りと判別できるようにします。
<div class="Block名__Element名">
</div>
例えば上記のロゴの場合はこのように命名します。基本的にBlock内のElementすべてにclass名を指定します。最初はElement名をどうすればよいのか迷うのでdiv要素の場合は文章構造的な名前を、その他要素はHTML要素名を使用するとよいかもしれません。
<div class="logo">
<div class="logo__main">
<img class="logo__img" src="img/logo.png" alt="ロゴ">
</div>
<div class="logo__sub">
<div class="logo__company-name">株式会社XD</div>
<div class="logo__company-text">会社の説明が入ります</div>
</div>
</div>
名前が2つ以上の単語になる場合
BlockやElementの名前の単語が2つ以上になる場合は「-(ハイフン)」で単語をつなぎます。
<div class="logo__company-name">株式会社XD</div>
<div class="logo__company-text">会社の説明が入ります</div>
Modifier
ModifierはBlock名やElement名の後に「-(ハイフン)」を2つでつなぎます。
<div class="Block名__Element名--Modifier名">
</div>
例えば上記のパーツの通常パーツを作成します。
<div class="intro-item">
<div class="intro-item__photo">
<img class="intro-item__img" src="img/photo.png">
</div>
<div class="intro-item__title">
タイトルが入ります
</div>
<div class="intro-item__text">
親譲りの無鉄砲で小供の時から損ばかりしている。
小学校に居る時分学校の二階から飛び降りて
一週間ほど腰を抜かした
</div>
<ul class="intro-item__list">
<li class="intro-item__list-item">
親譲りの無鉄砲で小供の時から損ばかりしている。
</li>
:
</ul>
</div>
リストのマーカーが「○」「■」で違うパーツにModifierを付与します。ul要素のclass名「intro-item__list」にModifier「intro-item__list–square」を追加します。
<div class="intro-item">
<div class="intro-item__photo">
<img class="intro-item__img" src="img/photo.png">
</div>
<div class="intro-item__title">
タイトルが入ります
</div>
<div class="intro-item__text">
親譲りの無鉄砲で小供の時から損ばかりしている。
小学校に居る時分学校の二階から飛び降りて
一週間ほど腰を抜かした
</div>
<ul class="intro-item__list intro-item__list--square">
<li class="intro-item__list-item">
親譲りの無鉄砲で小供の時から損ばかりしている。
</li>
:
</ul>
</div>
名前が2つ以上の単語になる場合
先程はElementで使用しましたが、Blockでも名前の単語が2つ以上になる場合は「-(ハイフン)」で単語をつなぎます。
<div class="intro-item">
</div>
命名規則をカスタマイズ(変則BEMを考える)
BEMはclass名が長くなるというデメリットをもっています。そのデメリットを少しでも軽減するための工夫。
名前が2つ以上の単語になる場合
名前の単語が2つ以上になる場合は「-(ハイフン)」で単語をつないでいましたがキャメルケース記法で命名する。
<div class="intro-item">
</div>
キャメルケース記法(2つ目以降の単語の頭文字を大文字にしてつなぐ)に変換します。
<div class="introItem">
</div>
BlockとElementとModifierの区切りを短くする
名前の単語が2つ以上になる時をキャメルケース記法にすることでModifier「-(ハイフン)」を2つにする必要がなくなり「-(ハイフン)」を1つでつなぐことができます。
Modifierに合わせてElementも「_(アンダースコア)」を1つでつなぎます。
<div class="intro-item">
<div class="intro-item__photo">
<img class="intro-item__img" src="img/photo.png">
</div>
<div class="intro-item__title">
タイトルが入ります
</div>
<div class="intro-item__text">
親譲りの無鉄砲で小供の時から損ばかりしている。
小学校に居る時分学校の二階から飛び降りて
一週間ほど腰を抜かした
</div>
<ul class="intro-item__list--square">
<li class="intro-item__list-item">
親譲りの無鉄砲で小供の時から損ばかりしている。
</li>
:
</ul>
</div>
上記をカスタマイズ版に変更します。ElementやModifierのつなぎが2つから1つに変更されます。
<div class="introItem">
<div class="introItem_photo">
<img class="introItem_img" src="img/photo.png">
</div>
<div class="introItem_title">
タイトルが入ります
</div>
<div class="introItem_text">
親譲りの無鉄砲で小供の時から損ばかりしている。
小学校に居る時分学校の二階から飛び降りて
一週間ほど腰を抜かした
</div>
<ul class="introItem_list-square">
<li class="introItem_listItem">
親譲りの無鉄砲で小供の時から損ばかりしている。
</li>
:
</ul>
</div>
Modifierをclass名から分離する
Modifierはバリエーションの為、「基本デザインのクラス名」に「Modifireのクラス名」を追加する形で記述します。
こうすることで複数Modifierを付与しても簡潔になります。
元の複数Modifier
<ul class="introItem_list introItem_list-square introItem_list-pickup">
</ul>
カスタマイズした複数Modifier
<ul class="introItem_list -square -pickup">
</ul>
<div class="introItem">
<div class="introItem_photo">
<img class="introItem_img" src="img/photo.png">
</div>
<div class="introItem_title">
タイトルが入ります
</div>
<div class="introItem_text">
親譲りの無鉄砲で小供の時から損ばかりしている。
小学校に居る時分学校の二階から飛び降りて
一週間ほど腰を抜かした
</div>
<ul class="introItem_list introItem_list-square">
<li class="introItem_listItem">
親譲りの無鉄砲で小供の時から損ばかりしている。
</li>
:
</ul>
</div>
上記をカスタマイズ版に変更します。Block名やElement名の後に「半角スペース」を入れ「Modifierを別クラス」として記述します。ただしModifierを意味するセパレータの「-(ハイフン)」を接頭辞として付与します。
<div class="introItem">
<div class="introItem_photo">
<img class="introItem_img" src="img/photo.png">
</div>
<div class="introItem_title">
タイトルが入ります
</div>
<div class="introItem_text">
親譲りの無鉄砲で小供の時から損ばかりしている。
小学校に居る時分学校の二階から飛び降りて
一週間ほど腰を抜かした
</div>
<ul class="introItem_list -square">
<li class="introItem_listItem">
親譲りの無鉄砲で小供の時から損ばかりしている。
</li>
:
</ul>
</div>
クラス名を分離した為、CSSは以下のような記述になります。
.introItem_list {
基本デザインを定義
}
.introItem_list.-square {
基本デザインから変更するところだけを定義
}
BEM以外のclass名を共存させるためBEM記法を明示する
BEMですべてのデザインを管理できればよいのですが、どうしてもBEMから外れてデザインすることもでてきます。BEMとそれ以外を区別するためにBEMのBlock名はパスカル記法(すべての単語の頭文字を大文字にする)を使用します。
<div class="introItem">
<div class="introItem_photo">
<img class="introItem_img" src="img/photo.png">
</div>
<div class="introItem_title">
タイトルが入ります
</div>
<div class="introItem_text">
親譲りの無鉄砲で小供の時から損ばかりしている。
小学校に居る時分学校の二階から飛び降りて
一週間ほど腰を抜かした
</div>
<ul class="introItem_list -square">
<li class="introItem_listItem">
親譲りの無鉄砲で小供の時から損ばかりしている。
</li>
:
</ul>
</div>
上記をカスタマイズ版に変更します。Block名「introItem」が「IntroItem」になります。
<div class="IntroItem">
<div class="IntroItem_photo">
<img class="IntroItem_img" src="img/photo.png">
</div>
<div class="IntroItem_title">
タイトルが入ります
</div>
<div class="IntroItem_text">
親譲りの無鉄砲で小供の時から損ばかりしている。
小学校に居る時分学校の二階から飛び降りて
一週間ほど腰を抜かした
</div>
<ul class="IntroItem_list -square">
<li class="IntroItem_listItem">
親譲りの無鉄砲で小供の時から損ばかりしている。
</li>
:
</ul>
</div>
案件内でルールが統一されていればよい為、より使いやすいようにBEMをカスタマイズしてみることをお勧めします。