We are ACORN!

プログラムやサーバーの設定など、技術的な記事を載せております。

HTMLコーディング プログラミング

BEMを使ってコーディングする

投稿日:

様々なクラス名の名づけルールがありますが、その中でもBEMはコンポーネント化のしやすさや、詳細度によるミスがないことなど、いくつか利点があります。

BEMの基本

ただBEMでの命名は分かりづらく、ルール化するのが難しいのではないかと思います。
実際BEMで検索してもルールが一つではなく、いくつも出てきます。

BEMの基本は別のサイトにお任せします。
まず私はプロジェクトに入る前に以下のサイトを読んでもらっています。
(大変お世話になっております!)

【CSS設計】ゼロからわかるBEM超入門

BEMの注意点

ネスト

まずBEMは役割の点でのBlock、Elementというものがあります。
これはあくまでも役割の点ということを意識する必要があります。
つまり「HTMLの構造とは違っているかもしれない」ということです。

HTML上では親子関係にある要素がBEM上はすべてElementになっている、なんてことは良くあります。

そこで押さえておきたい点として、Blockはネストできる、Elementはネストできない、という点です。

Elementはネストできないので、block__element__other-elementという名前を付けることは出来ません。

もしどうしてもネストしたい場合は、子Blockを作ります。
つまり、

<section class="block">
  <div class="block-child">
    <span class="block-child__element">
      ...
    </span>
  </div>
</section>

のような形にします。
この場合block-childは違うBlockなので、blockから切り離されてもいいように作るか、blockblock-childは密結合していることを利用者が分かるようにしておく必要があります。
密結合している場合はCSS内にコメントとして残しておくか、結合元の名前を-の前に入れるなどのルールを作っておくといいかもしれません。
ただ、密結合することを許すと、結局どんどんと密結合が生まれていき、普通のCSSと大差なくなってしまう可能性があります。
できるだけ、Blockは単体でも表示できるように作っておきましょう。

CSSのセレクタ

命名はBEMで出来たとしても結局CSS内で子孫セレクタを使ってしまうと「詳細度を均一に保つ」というBEMの目標からそれてしまいます。

どういうことかというと、

.block .block-child {
  /* 詳細度は0-2-0 */
}

.block-child {
  /* 詳細度は0-1-0 */
}

.block .block-childと書いてしまうと、詳細度が上がってしまいます。
本来は詳細度を0-1-0でそろえたいわけです。そうすると基本的に並び順だけが問題になるので判断が楽になります。

以上の2点を考えつつ、BEMの実装を行っていきます。

実際の実装

カンプ

単純ですが、

・メインビジュアル
  ・メインビジュアルに重なるかたちで商品名とキャッチコピー
・キャンペーン部分
  ・画像
  ・宣伝文

という構造です。

headerはハンバーガーメニューやPC版ではナビゲーションなどが入ることを想定します。カンプにはないので割愛します。

<main class="main">
  <section class="mv">
    <h1 class="mv__productname">商品名</h1>
    <div class="mv__catchcopy">キャッチコピーキャッチコピー</div>
  </section>

  <section class="campaign">
    <h2 class="campaign__title">キャンペーン</h2>

    <div class="campaign__container">
      <picture>
        <source srcset="assets/images/product_img_pc.jpg" media="(min-width: 768px)">
        <img class="campaign__picture" src="assets/images/product_img_sp.jpg" alt="">
      </picture>
      <p class="campaign__text">
        Lorem ipsum dolor sit amet,
        consectetur adipiscing elit,
        sed do eiusmod tempor incididunt ut
        labore et dolore
        magna aliqua. Ut enim ad
        minim veniam, quis nostrud
        exercitation ullamco laboris
        nisi ut aliquip.
      </p>
    </div>
  </section>
</main>

こんな感じでしょうか。
mv = Main Visualの略や、imgなどの略された単語はありますが、概ね単語をそのまま書いています。
単語の区切れ目は-のケバブケースにします。

先ほども書きましたが、HTMLの親子構造はBEMには適用されていません。
campaign__containerの中に横並びの二つの要素がありますが、どちらもBEM上はcampaignのElementという扱いです。

Modifier

もしこのキャンペーンBlockが複数出てきて、なおかつ背景色が違う、などの変化が出た場合は、違うエレメントを作るかModifierを使います。

今回はちょっと暗めのエリアに入るキャンペーンBlockなので--darkというModifierを作ることにします。
キャンペーン内のタイトルも一緒に変える必要があります。

<section class="campaign campaign--dark">
  <h2 class="campaign__title campaign__title--white">キャンペーン</h2>
</section>

こんな感じですね。

.campaign--darkは背景色などの変化分だけ、.campaign__title--whiteは文字の色などの変化分だけのスタイルを書きます。
要するにCSSにModifierのセレクタが記述されていなくても、きちんと表示できるようになっているわけです。

決して.campaing--dark .campaign__titleというセレクタで色を変えようと考えてはいけません。そうすると詳細度が変わってしまいます。

例えば、

<section class="campaign campaign--dark">
  <h2 class="campaign__title">キャンペーン</h2>
</section>

.campaing--dark .campaign__title {
  color: white;
}

こうして文字色を変えたとします。
その後別の人が正規の書き方でModifierを書き加えました。

<section class="campaign campaign--dark">
  <h2 class="campaign__title campaign__title--yellow">キャンペーン</h2>
</section>

.campaing--dark .campaign__title {
  color: white;
}

.campaign__title--yellow {
  color: yellow;
}

しかし、詳細度が.campaing--dark .campaign__titleの方が高いので.campaign__title--yellowは反映されません。

実証のサンプル

こういった事態を避けるために、必ず詳細度を均一に保つ必要があるわけです。

さいごに

BEMはコンポーネント化に役立つので利用するシーンが多いと思います。
ただ今後@scopeという新しいCSSが普及してくると、そちらに移行していく可能性があります。
BEMはクラス名が長くなるので@scopeの方がコーディングが楽だと思います。

それでも現在採用するには最善の選択肢かもしれません。
ぜひ活用していきましょう!

-HTMLコーディング, プログラミング


comment

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)

関連記事

【PHP】ビルトインウェブサーバーで楽々テスト環境

teratailで質問に答えるようになったら、以外にサーバー立てずにテストして、ローカル制限に引っかかっている人が多いので、簡単に立てられるローカルサーバーの構築方法を書いておこうと思います。 まず、 …

【PHP】 Macからの日本語名ファイルを正しく扱う

久しぶりに仕事ではまりました。 ファイルをアップロードして、その日本語名を利用するシステムなのですが、Macも含まれます。 それで、会社からMac miniを借りてダウンロード、アップロード実験をして …

MarkDownDiagram

マークダウンで画面遷移図などのダイアグラムを作れるツールをブラウザベースで作ってくださった方がおられます。 大変重宝していて、業務で使いまくりです。 https://github.com/wakufa …

Visual Studio CodeでWSL上のPHPをデバッグ

前書き Sublime Text 3を愛用しているんですが、だんだん他のエディタが追いついて、追い抜いて来たような感じがします。 Sublime Textは更新が止まってしまっているので、まあしょうが …

CSS3

Perfect Pixel で調整してみよう!

皆さんはPerfect PixelというChromeの拡張機能をご存じでしょうか? デザインカンプを半透明にしてWebページに重ね、要素のズレなどを確認できるものです。 そんなに厳密にWebページを作 …