BEMを実際に使ってみて困ったこと|クラス名が長くなる・Block名に迷う問題

BEMって難しくない?クラス名で迷ったときの考え方

前回の記事では、CSSの命名規則「BEM」について紹介しました。

BEMは、

Block__Element--Modifier

というルールでクラス名を付けることで、CSSを分かりやすく管理する方法です。

実際に使ってみると、最初は「なるほど、分かりやすい」と思います。

ところが、サイトを作っていると次のような疑問が出てきます。

  • HTMLの階層が深くなるとクラス名が長くならない?
  • 複数のBlockを囲む要素には、何というBlock名を付ければいい?
  • ページが増えたらクラス名が他のページとぶつからない?

今回は、BEMを実際のWeb制作で使うときに迷いやすいポイントについて、自分なりの考え方をまとめます。

HTMLの階層が深くなるとクラス名が長くならない?

そもそもBEMはHTMLの階層をそのまま表すものではない

まず、BEMを使うときに意識したいのが、

HTMLの階層とBEMの階層は別物

ということです。

例えば、次のようなHTMLがあったとします。

<div class="card">
  <div class="card__body">
    <div class="card__content">
      <h2 class="card__title">タイトル</h2>
    </div>
  </div>
</div>

タイトルのクラス名を考える際、HTMLの階層に合わせて、

card__body__content__title

としたくなるかもしれません。

しかし、これはBEMでは基本的に避けます。

BEMでは、

Block__Element

という関係を基本にするためです。

そのため、

<h2 class="card__title">

のように、Blockであるcardから直接Elementを作ります。

Blockは1単語でなくてもOK

BEMのBlockは、必ずしも1単語で名前を付ける必要はありません。

例えば「会社情報のカード」を表すBlockなら、

company-card

のように、複数の単語をハイフンでつないで名前を付けることができます。

このように、単語をハイフンでつなぐ記法を**ケバブケース(kebab-case)**といいます。

例えば、

company-card
news-list
service-button
contact-form

などです。

この場合、

company-card

全体が1つのBlockです。

「companyとcardの2つのBlockがある」という意味ではありません。

あくまで、

company-cardという名前の1つのBlock

と考えます。

Block名を付けるときは、その部品の役割が分かりやすい名前になるように、必要に応じて複数の単語を組み合わせてOKです。

「Blockは1単語」というルールではないので、company-cardのような名前も普通に使えます。

複数のBlockを囲むBlockには何という名前を付ける?

これも悩みやすいところです。

例えば、

<div class="???">
  <section class="company-card">...</section> 
  <section class="news-list">...</section> 
  <section class="service-card">...</section>
</div>

のように、複数のBlockを囲む要素を作りたいとします。

「このdivは何というBlockなんだろう?」と迷います。

ここには絶対にこの名前を付ける、という正解があるわけではありません。

例えば、

contents

や、

wrapper

など、サイト内で役割が分かる名前を付ければよいでしょう。

「wrapperの中にcompany-cardがあるなら、wrapper-company-cardとしないといけないのでは?」

と思うかもしれませんが、その必要はありません。

BEMでは、HTML上の親子関係をそのままクラス名にするわけではありません。

company-cardが独立したBlockなら、そのままcompany-cardでOKです。

ページが増えるとクラス名がぶつからない?

例えば、

.card

というBlockを作ったとします。

別のページでも、

.card

という名前を使いたくなるかもしれません。

BEMを使っているからといって、クラス名が絶対に衝突しないわけではありません。

そこで、サイトの規模によってはBlock名にページや機能を含める方法があります。

例えば、

company-card
service-card
news-card

のようにします。

そうすると、

company-card__title
service-card__title
news-card__title

と、それぞれの役割が分かりやすくなります。

何でもページ名を付ければいいわけではない

ただし、すべてのクラスにページ名を付ける必要はありません。

例えば、サイト全体で共通して使うボタンなら、

button

で問題ありません。

一方、そのページ専用の特殊なカードなら、

service-card

のように、より具体的な名前にすることができます。

つまり、

「サイト全体で共通するもの」と「そのページ・機能専用のもの」を分けて考える

のがおすすめです。

BEMを厳密に守りすぎない

BEMにはルールがありますが、Web制作ではルールを守ること自体が目的にならないようにすることも大切だと思います。

例えば、

main-container-inner-box__title

のようなクラス名になってしまったら、

「BEMだから正しい」

と考えるのではなく、

「そもそもこの構造をそんなに細かく名前付けする必要がある?」

と考えてみます。

CSSを管理しやすくするためのBEMなのに、クラス名が長くなりすぎて逆に分かりにくくなってしまっては本末転倒です。

BEMは目的ではなく、CSSを分かりやすくするための手段

BEMはCSSを整理するための便利な考え方です。

ただ、実際のWeb制作では、

BEMのルールを100%守ることより、後から見たときに分かりやすいことの方が重要

だと思います。

BEMは「絶対にこう書かなければいけない」というものではなく、CSSを管理しやすくするための考え方のひとつとして使うくらいがちょうどいいのではないでしょうか。

まとめ

BEMを使い始めると、Block__Element--Modifierという基本ルールは分かっても、実際のWebサイトでは「じゃあ、この場合はどうする?」という疑問が出てきます。

個人的には、こういった場面ではBEMのルールを機械的に当てはめるのではなく、その要素に役割があるか、後から見て分かりやすいかを考えるのが大切だと思います。

BEMはCSSを書くためのルールというより、CSSを整理して、あとから見ても分かりやすくするための考え方として使うくらいがちょうどいいのかもしれません。

おとうふ

田舎で働くWebエンジニア

毎日少しずつ成長中🌱
仕事・学習・暮らしの中で、自分が実際に経験したことを発信