この記事は、ラクスパートナーズ AdventCalendar 2025の6日目の記事です。
(個人で25日連続投稿にチャレンジ中のカレンダーになります)
本日は、クラス命名規則のBEMについてまとめたいと思います。
BEMとは
BEMは、クラス名の衝突を避ける命名規則です。
- Block
- Element
- Modifier
という3つの要素から成り立っており、これらの頭文字をとって「BEM」という名前がつけられました。
Blockは「大枠」の役割を持ちます。
ElementはBlockの中の要素(部品)の役割を持ちます。
Modifierは同じBlockやElementの中で適用するスタイルを分けたい時に使います。
書き方
BEMの基本的な書き方は以下となります。
<div class="block__element --modifier"></div>
blockとelementの間は「__」、elementとmodifierの間は「--」で区切っています。
これだけでは分かりづらいと思うので、簡単なお問い合わせフォームを例にご説明します。
<div class="contact">
<label class="contact__label">お名前</label>
<input class="contact__input" />
<label class="contact__label">メールアドレス</label>
<input class="contact__input" />
<button class="contact__btn">送信する</button>
<button class="contact__btn --red">キャンセル</button>
</div>
.contact {
&__label {
// 省略
}
&__input {
// 省略
}
&__btn {
color: blue;
// 省略
&.--red {
color: red;
}
}
}
上記の例では、
- お問い合わせフォームの大枠となる「contact」というdiv要素がBlock
- label要素やinput要素、button要素がElement
- キャンセルボタンについている「--red」というクラスがModifier(送信ボタンは青文字なのに対して、キャンセルボタンは赤文字になる)
という構造となっています。
BEMのメリット
保守性が高い
他の開発メンバーと同じクラスを命名した場合、想定通りのスタイリングを適用できない恐れがあります(CSS)。
!importantを使えば上書きすることも可能ですが、管理が複雑になるため、!importantの多用は避けた方が無難です。
BEMであれば、クラス名が衝突する可能性は低くなります。
第三者から見てもHTMLの構造がわかりやすい
レビューの際に「ここからここまでは同じBlockで構成されている」など、HTMLの構造がどうなっているかを理解しやすくなります。
SCSSと相性が良い
SCSSを導入している場合、BEMは非常に相性が良いです。「書き方」の例でもお見せしたように、&(アンパサド)でElementやModifierを
&__element
&.--modifier
といった形式で繋げることができるので、SCSS内でも構造がわかりやすく、スタイルの修正も容易になります。
その他のルール
ここからは、私が良いなと思っている、BEMに関する細かいルールを記載いたします。
Elementの下にElementをネストさせる命名はしない
<nav class="menu">
<ul class="menu__list">
<li class="menu__list__item"></li>
<li class="menu__list__item"></li>
</ul>
</nav>
このように、「__list」と「__item」を連結させていますが、これを禁止する、というものです。
(HTMLのネストが深い時に命名が長くなってしまうからですね)
<nav class="menu">
<ul class="menu__list">
<li class="menu__item"></li>
<li class="menu__item"></li>
</ul>
</nav>
このように、どれだけ親子関係がネストしていても、「Block__一つのElement」という形にしています。
--Modifierはマルチクラスにする
「block__element」と「--modifier」を別々のクラスにして扱う、というものです。
これは通常のBlockやElementとの差分だけを書けばいいからです。
block__element--modifierのような形で1つのクラスとして連結させてしまうと、block__elementとblock__element--modifierで同じスタイルを適用しなければなりません。
しかし、「--modifier」をマルチクラスとして切り離してしまえば、「--modifier」の差分のみを追加すれば良いため、CSSの記述量が少なくてすみます。
BlockにModifierをつけても良い
基本形は「block__element--modifier」ではありますが、同じBlock同士でもバージョン違いのものを作りたい、というケースがあるため、「block --modifier」という形にしても良いとしています。
その他
他にも
- 複数単語で命名するときはキャメルケース(またはケバブケース)
- タグ名やidにスタイルを当ててはいけない
- Blockの子ではないElementに「block__element」を適用してはいけない
などの細かいルールがありますが、プロジェクトごとに話し合って、自分たちに合うものを選択していくと良いと思います。
ここまでBEMについて書きましたが、Vue.jsでscoped(指定したコンポーネントのみにCSSを適用できる機能)が実装されたりと、最近ではCSSの汚染を防ぐ機能も出てきています。そのため、現在はCSSの汚染防止の目的でBEMを採用するメリットは少ないかもしれません。
しかし、BEMには「HTMLの構造がわかりやすい」「SCSSと相性が良い」といったメリットもありますので、SCSSを導入しているプロジェクトがあれば採用を検討してみてください。
もし「うちの現場ではこんな命名規則を採用しています!」などあれば、是非コメントいただけますと幸いです。
ここまで読んでくださりありがとうございました。