CHROMA

世の中の "当たり前" を確認する

BEM とは

メンテナンスブルな CSS の設計の話で OOCSS や SMACSS ってのがあるけど、そのうちの一つで BEM というのがある。
http://bem.info/

BEM-Methodology Definitionsの日本語訳 を見てみると XJST とか BEMHTML とかいうテンプレートエンジンに関する内容(よくわかってない)も書かれてるんだけど、日本ではこの中の BEM を CSS 用に使いやすくした MindBEMding日本語訳はこっち )の命名規則が良いってことで流行ってるみたい。
また、今 BEM っていったら大体は MindBEMding のことを指してるみたい。

BEM-Methodology Definitions の内容全部をこれから理解しようとすると自分が知らない知識が多くてちょっとアレなので.. 、MindBEMding の内容を先に抑えておきたいと思う。
BEM Advent Calendar 2013 では BEMツール を試している強者( @GeckoTang さん)もいるので、気になる人は見てみたらどうだろう。

BEM のルール

Block, Element, Modifier の頭文字を取って BEM って名付けられてる。

  • Block .. アプリケーションの構成要素 に当たるもの。単体の Block (状況によるけど table とか)もあれば複数の Block を含む複合物(ロゴやメニューを含むヘッダーとか)のものもある。
  • Element .. Block の構成要素 (検索 Block 内の入力欄とボタンとか)。
  • Modifier .. 元となる Block や Element で一部スタイルの変更が必要な時にに使うもの

BEM はモジュール単位で HTML・CSS を組むことになるので、クラス名の先頭は必ず Block になる。
また、BEM の各カテゴリーを表現するために Element ではアンダースコア 2つ( __ )を名前の前に置き、Modifier ではハイフン2つ( -- )を名前の前に置いて各カテゴリーを連結する。

BEM の何が良いのか

  • クラス名が明快になる
  • 他のクラスへの継承問題などが減る

クラス名が明快になる

.contacts_web_form_heading

前後の文脈をしっかり理解せず読んでしまうと contacts_webform_heading で切って読む人、 contactsweb_formheading で読む人、 contacts_web_formheading で読む人など、人によって解釈が分かれてしまう。

.contacts__web_form__heading

のように、 contacts Block に続けて Element の時はアンダースコア 2つ( __ )を前に置いて単語の区切りを付けておくことで、誰が見てもわかりやすくなる。

他のクラスへの継承問題などが減る

以下のようなものを子孫要素にスタイルを当てる形で書くとこうなりそう ( http://jsdo.it/thleap/7HnI ):

<section class="contents">
  <h1>コンテンツタイトル</h1>
  <article class="article">
    <h1>記事タイトル</h1>
    <h2>記事サブタイトル</h2>
  </article>
</section>
.contents {
  ..
}

.contents h2 {
  padding-left: 5px;
  border-left-width: 5px;
  border-left-style: solid;
  border-left-color: tomato;
  font-size: 18px;
  color: tomato;
}

.contents .article {
  ..
}

/* .contents h2 のスタイルが継承される */
.contents .article h1 {
  font-size: 24px;
}

BEM のように最初の Block 以下の要素全てにクラスを振るようにすると、親からの継承で意図しないスタイルが当てられることが無くなる ( http://jsdo.it/thleap/76L9 ):

<section class="contents">
  <h1 class="contents__heading">コンテンツタイトル</h1>
  <article class="contents__article">
    <h1 class="contents__article__heading">記事タイトル</h1>
    <h2 class="contents__article__subheading">記事サブタイトル</h2>
  </article>
</section>
.contents {
  ..
}

.contents__heading {
  padding-left: 5px;
  border-left-width: 5px;
  border-left-style: solid;
  border-left-color: tomato;
  font-size: 18px;
  color: tomato;
}

.contents__article {
  ..
}

/* .contents__heading のスタイルは継承されない */
.contents__article__heading {
  font-size: 24px;
}

.contents__article__subheading {
}

試しに書いてみる

ここで突拍子もなく「 BEM ってこういう風に書くものなのかな」というのを書いてみる:

<div class="contacts">
  <h1>お問い合わせ</h1>
  <div class="contacts__web_form">
    <h2 class="contacts__web_form__heading">WEB フォームからのお問い合わせ</h2>
    <a href="" class="button contacts__web_form__button">フォームに遷移</a>
  </div>
  <div class="contacts__telphone">
    <h2 class="contacts__telphone__heading">お電話からのお問い合わせ</h2>
    <address class="contacts__telphone__phone_number">
      <a href="tel:000-0000-0000">000-0000-0000</a>
    </address>
    <small class="contacts__telphone__note">お電話は平日l0時〜19時まで受け付けております</small>
  </div>
</div>

クラス振ってモバイル対応させる( Modifier つかう)ってなったら、こんな感じかな:

<div class="contacts--mobilde">
  <h1>お問い合わせ</h1>
  <div class="contacts--mobilde__web_form">
    <h2 class="contacts--mobilde__web_form__heading">WEB フォームからのお問い合わせ</h2>
    <a href="" class="button contacts--mobilde__web_form__button">フォームに遷移</a>
  </div>
  <div class="contacts--mobilde__telphone">
    <h2 class="contacts--mobilde__telphone__heading">お電話からのお問い合わせ</h2>
    <address class="contacts--mobilde__telphone__phone_number">
      <a href="tel:000-0000-0000">000-0000-0000</a>
    </address>
    <small class="contacts--mobilde__telphone__note">お電話は平日l0時〜19時まで受け付けております</small>
  </div>
</div>

この方法を自身のコーディングにどう取り入れるか

僕はいま SMACSS のやり方でカテゴリーを分けて CSS を書いてるけど、その中でもモジュールカテゴリーは BEM の命名規則とよく合いそう。使ってみよう。

参考