💭

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

2021/10/17に公開
1

はじめに

この記事はCSS設計 BEMについて初心者の方向けにわかりやすく解説した記事です。
できるだけ正確な情報を記述することを意識していますが、間違ったこともあると思います。なのでこの記事でざっと概要を掴んだ後は、BEM 公式ドキュメントを参照することをおすすめします。

BEMの基本「Block」「Element」「Modifier」

それでは、BEMの基本「Block」「Element」「Modifier」について解説していきます。

Block(ブロック)とは

Blockとは「機能的に独立した再利用可能なモジュール」と定義されています。
難しいですね。
簡単にいうと、「どのページでも使い回すことができるパーツ」をブロックと呼んでいます。

Blockの命名規則

まずはブロックの命名規則を見ていきます。

  • クラス名はモジュールの「見た目(赤や大きい)」ではなく「それが何であるか(メニューやボタン」を表すようにします。
  • 英単語が2つ以上の場合はハイフンで繋げて書きます。(ハイフンケース)
<!-- × 見た目の説明になってる -->
<div class="red-text-btn"></div>
<!-- ○「何であるか」を説明している -->
<div class="error-btn"></div>

Blockのネスト

  • ブロックはネストすることができる
  • ネストの数に制限がない

例えば、下の図のように一番大きな枠としてヘッダーブロックがあり、その中にメニュー、ロゴ、検索、ログインなどのブロックを含めることができます。


Nested structure

<!-- ヘッダーブロック -->
<header class="header">
  <!-- ネストされた メニューブロック -->
  <div class="menu"></div>
  <!-- ネストされた ロゴブロック -->
  <div class="logo"></div>
  <!-- ネストされた 検索ブロック -->
  <form class="search"></form>
  <!-- ネストされた ログインブロック -->
  <form class="auth"></form>
</header>

Blockについて詳しく

ブロックは「コンテキストに依存せず、どのページに配置されても同じように機能するモジュール」です。
ブロックには周りに影響を及ぼすスタイリング(padding,margin,positonなど)を使いません。周りに影響を及ぼすスタイリング、つまりレイアウトや配置を指定したい場合は、後述するMixというテクニックを用いて実装します。

ブロックは、ページ上で移動したり、ページやプロジェクト間で移動したりすることができます。
ブロックを独立したモジュールとして実装することで、ページ上の位置を変更することが可能になり、ブロックの適切な機能と外観が保証されます。

例えば下の図のように、ブロックのCSSやJavaScriptのコードを変更することなく、ロゴと認証フォームを入れ替えることができます。

Arbitrary placement


Arbitrary placement

Element(要素)とは

Element(要素)とは「Blockを構成する要素で、Blockの外では独立して使用できないもの」です。
例えば、先ほどのブロックの例であげたメニューブロックは、4つの要素で構成されていることが分かります。


Element

Elementの命名規則

Elementの命名規則を見ていきます。

  • Elementのクラス名は、Blockの名前を継承し、アンダースコア2つ記述した後にElementの名前を付ける
<!-- 検索ブロック -->
<form class="search-form">
  <!-- `input` は検索ブロックの要素 -->
  <input class="search-form__input">
  <!-- `button` は検索ブロックの要素 -->
  <button class="search-form__button">Search</button>
</form>

Elementのネスト

注意点として、Elementの中にElementがネストされた命名をしてはいけません。
つまりブロックの要素(Element)を作るのはOKだけど、要素(Element)の要素(Element)を作るのはダメってことです。

これを許すと要素を入れ替えたり、削除したり、追加したりすることができなくなるからです。
ただし、要素の中に要素がネストされているのはOKです。
ややこしいですね。

  • 「ブロック名__エレメント名」は正しい使い方
  • 「ブロック名__エレメント名__エレメント名」は間違い
<!-- 検索ブロック -->
<form class="search-form">
  <!-- × `span` が`button`の要素になってる -->
  <button class="search-form__button">
    <span class="search-form__button__text">Search</span>
  </button>
</form>
<!-- 検索ブロック -->
<form class="search-form">
  <!-- ○ `span` は検索ブロックの要素 -->
  <button class="search-form__button">
    <span class="search-form__text">Search</span>
  </button>
</form>

ElementのCSSの記述

CSSを記述するときは、子孫セレクターを使わず、詳細度を均一に保ちます。
Block内の構造が変わっても、個々の要素のコードを変更することなく対応できるようにするためです。
難しく言えば「特定のコンテキストに依存しない」ようにします。
こうすることで、レイアウトが変わっても柔軟に対応できるようになります。

/* × 要素の詳細度が高い */
.menu {}
.menu .menu__item {}
.menu .menu__bun {}
/* ○ 詳細度が均一 */
.menu {}
.menu__item {}
.menu__bun {}

Elementは独立できない

要素は常にブロックの一部であり、ブロックから切り離して使用することはできません。

<!-- 間違った使い方 -->
<form class="search-form">
  <input class="search-form__input">
</form>
<!-- 要素が独立している -->
<button class="search-form__button">Search</button>

Elementはなくてもいい

要素は任意のブロック構成要素です。すべてのブロックに要素があるわけではありません。

<!-- 検索ブロック -->
<div class="search-form">
    <!-- インプットブロック -->
    <input class="input">
    <!-- ボタンブロック -->
    <button class="button">Search</button>
</div>

Modifier(修飾子)とは

Modifierは修飾子という意味で、モディファイアと読みます。
モディファイアとは「BlockやElementの見た目、状態、振る舞いを定義するもの」です。

例えば、メニューブロック(menu)は、モディファイアの使い方によって見た目が変わります。
下の図では、メニューブロックにモディファイアを加えることで、見た目やレイアウトが変わっています。


Modifier

Modifierの命名規則

モディファイアのクラス名は、モディファイアを適用したいBlockやElementの名前を継承し、ハイフン(--)2つを記述した後にモディファイアの名前をつけます

<!-- 検索ブロックに `focused`というモディファイアで修飾している -->
<form class="search-form search-form--focused">
  <input class="search-form__input">

  <!-- ボタン要素に `disabled`というモディファイアで修飾している -->
  <button class="search-form__button search-form__button--disabled">Search</button>
</form>

Modifierは3パターン

モディファイアは概ね3つのパターンに分けられます。

  1. 見た目 - どんなサイズか?どの色か?どのテーマに属するか?
    例: small(小さい)、caution(警告)
  2. 状態 - 他のBlockまたはElementと比べて何が違うか?
    例: disable(使用不可)、active(アクティブな状態)
  3. 振る舞い - それがどのように振る舞うか(動作するか)?
    例: bottom-right(右下に位置する)

Modifierは複数使える

1つのブロック、要素に対して、モディファイアは複数使えます。

<form class="form form--large form--focused">
  <button class="form__button form__button--small"></button>
  <button class="form__button form__button--small form__button--error"></button>
</form> 

おわりに

今回はBEMの基本的な考え方「Block」「Element」「Modifier」について解説しました。あまり難しくならないように簡単なHTMLに絞った説明をしましたが、次回はCSSの書き方Mixという書き方について解説していきます。

参考文献

BEM
BEMの公式ドキュメント

MindBEMding
本来のBEMの命名規則をカスタマイズして、より使いやすくしたもの。
本記事では、このMindBEMdingを採用しています。

CSS設計完全ガイド
CSS設計の基本から、OOCSS、SMACSS、BEM、PRECSSまでをとてもわかりやすく解説してくれています。また、実践的なプラクティスもあり、たくさんのモジュールを例に出し、その都度の最適解のコードが解説されているのでとてもおすすめです。
著者の半田惇志さんは、PRECSSというCSS設計を開発した方なのでCSS設計を学ぶ際に信頼して学べる1冊です。

Discussion

KentaroxKondoKentaroxKondo

すごくわかりやすかったです!ありがとうございます。Mixの使い方も楽しみにしています。