N.Y.C. Tech Library

ホームページの制作テクニックや日常のハックを綴る

WEB制作

【CSS設計】今さら聞けないBEMの基本【初心者・入門】

投稿日:2019年2月18日 更新日:

今回は今さら聞けないBEMの基本ということで、CSS設計にまつわるエントリです。

「この要素にはなんてクラス名をつけたらいいんだ・・・」という悩みはWebコーダーが必ずぶつかる課題だと思います。
その時は自分流のルールでいいかもしれませんが、後で編集するときやチームメンバーに読んでもらう時にわかりにくくなってしまうこともしばしば・・・。

だから、命名規則には広く普及しているCSS設計思想を流用するのがいいんです。
制作会社ではBEMや他の設計思想をベースにしたコーディング規約が設定されていることも珍しくないでしょう。
今回は初心者向けにBEMという命名規則の基本をご紹介します。

BEMとは

CSS設計思想にはOOCSS、BEM、SMACSS、MCSS、FLOCSS、FLOUなどいくつかありますが、その中でもBEMはクラス命名規則として後続のCSS設計思想に取り込まれている有名なものです。
正確にはBEMの発展系であるMindBEMdingというのが有名なようなのですが、英語なのでBEMについて書いているブログ等を参照した方が早いかもしれません。

BEMはBlockElementModifierの頭文字を表しており、UIパーツの塊をBlockという起点にして、その構成要素をElementで、バージョン違いなどをModifierで示します。
BEMの特徴にして利点は、このBlock、Element、Modifierを1つのクラス名の中で表現するところにあるのですが、文章だけだとわからないと思うのでさっそく例を見てみましょう。

さっそく例を見てみましょう

以下が基本形です。

<div class="block">
  <span class="block__element"></span>
</div>
  • 基本的にidは使わず、classで指定します。
  • blockはUIパーツの塊(起点)を示します。
  • elementはblockの構成要素を示します。
  • blockとelementはアンダーバー2つで繋ぎます。

バージョン違いなどは以下のようにクラスを追記します。

<div class="block block--modifier">
  <span class="block__element block__element--modifier"></span>
</div>
  • modifierはバージョン違いや一時的な状態を示します。
  • modifierはハイフン2つで繋ぎます。
  • modifierはblockにもelementにもつけてOKです。

文章だと小難しいことが書いてありましたが、実際に見てみると簡単だと思いませんか?

文字の区切りはハイフン1つ

<div class="primary-block">
  <span class="primary-block__element"></span>
</div>

blockとelementの塊がわかりやすくなるため、接続はアンダーバー2つなんですね。

elementのネストは禁止

よくやってしまうアンチパターンとして、elementのネストがあります。

//ダメなパターン
<div class="block">
  <ul class="block__list">
    <li class="block__list__item"></li>
  </ul>
</div>

やっていしまいたくなる気持ちはわかりますが、elementの依存関係が複雑になっていくためアンチパターンとされています。 正しい方法としては2通りあげられます。状況に応じて使い分けてください。

//正しいパターン1
<div class="block">
  <ul class="block__list">
    <li class="block__list-item"></li> //blockの構成要素として
  </ul>
</div

正しいパターン1のようにelementの中に同じレベルのelementが入るのはOKです。
この場合、listはblockの外で再利用することはできません。

//正しいパターン2
<div class="block">
  <div class="block__list">
    <ul class="list">
      <li class="list__item"></li> //listの構成要素として
    </ul>
  </div>
</div

また、正しいパターン2のようにblockの中に別のblockが入るのもOKです。
この場合、listはblockの外でも同様のUIパーツとして再利用できます。 (そのようにCSSを設計すべきです)

elementはblock内にしか存在できない

//ダメなパターン
<div class="block">
  <ul class="primary__list"> //突然primary__listが登場している
    <li class="primary__list-item"></li>
  </ul>
</div>

起点となるblockがないelementは存在してはいけません。

//これもやめましょう
<div class="primary">
  <div class="secondary">
    <span class="primary__child"></span> //secondaryの中にprimary__child
  </div>
</div>

起点となるblockが直近のblockの外側にあるのも依存関係が複雑になるのでやめましょう。

バージョン違いをmodifierで表す方法

modifierはblockやelementのバージョン違いを示しますが、曖昧な概念で使い方も難しいので、チームで制作する場合は使い方について共通認識が必要です。

ここではmodifierの使い方をの一例をSCSSで紹介します。
この例ではSCSSの&を使ってセレクタのネストを実現していますが、&を使ったネストはアンチパターンという話もあるので注意してくださいね。

//HTML
<div class="button button--red">
  <a class="button__link">button</a>
  <span class="button__ornament"></span>
</div>
//SCSS
.button {
$this: &; //.buttonを$thisに退避しておく
// ...

    &--red { //&を使ってmodifierを付加
        // redバージョン
    }
    &__link {
        // ...
        
        #{$this}--red & { //退避した.buttonを使う
            // redバージョン
        }
    }
    &__ornament {
        // ...

        #{$this}--red & { //退避した.buttonを使う
            // redバージョン
        }
    }
}
//CSS
.button {
    // ...
}
.button--red {
    // ...
}
.button__link {
    // ...
}
.button--red .button__link{
    // ...
}
.button__ornament {
    // ...
}
.button--red .button__ornament{
    // ...
}

これはあくまでも一例です。
他のやり方についてはBEMのmodifierでスタイルを切り替える時の書き方が詳しいので、読んでみると面白いかもしれません。

blockにするかelementにするか迷ったら

原則として、一つの要素に複数のブロック・エレメントを設定することは避けましょう。
そして、blockにするかelementにするか迷ったらblockにしましょう。

<section class="section">
  <div class="section__inner">
    <h2 class="section__title">title</h2>
    <div class="section__content">
      <ul class="card-container">
        <li class="card">
          <h3 class="card__title"></h3>
          <div class="card__content">
            <p class="card__image-wraper">
              <img class="card__image" src="card_thumb.png" alt="">
            </p>
            <p class="card__text">text</p>
          </div>
        </li>
        <li class="card"><!-- 省略 --></li>
      </ul>
    </div>
  </div>
</section>

あくまでも一例ですが、section, card-container, cardの3ブロック登場しています。

このようにすることで、section__contentの中身を入れ替える時やcardを使い回す時に楽になります。多少divが増えてもblockが別れていた方が後の修正が楽ですので、参考にしてみてください。

 

まとめ

  • BEMはクラスの命名規則として有名なCSS設計思想
  • block__element–modifierというのがクラス名の基本構造。
  • elementのネストは禁止
  • elementはblock内にしか存在できない
  • バージョン違いや一時的な状態はmodifierで表す、使い方には工夫が必要
  • 迷ったらdivやspanを増やしてもいいのでblockにする

ここまで簡単に説明してきましたが、なんとなく理解できたでしょうか?
詳しく解説しているブログは他にもたくさんあるので、色々読んでみることをお勧めします。
それでは、よいコーディングを!

-WEB制作
-

執筆者:


comment

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

thirteen + ten =

関連記事