ホームページの構築作業に関わっていると、「もっとCSSを効率的に書きたい」と感じたことが一度はあるのではないでしょうか。

CSSが1996年に誕生してから20年以上経ち、サポート等は充実してきたものの書き方については特段簡素化されてはいません。
その中で「もっと効率的にCSSを書きたい」という要望を拾って具体化されていったのがBEM(ベム)と呼ばれる概念です。

CSSを効率的に書くことは、時間の短縮になるだけでなく、保守運用の面でもメンテナンスしやすくなります。
今回は、CSSを機能的にマークアップする概念「BEM」について、基本的な考え方や具体的なコーディング方法を解説します。

BEMが生まれるまで

bem.png
Built on Pablo

比較的小規模のサイトであれば、体系的にCSSを書く必要はあまりないかもしれません。
小規模サイトの場合は簡単なCSSを早速書いてみたり、SASSのようなプリプロセッサーを使ったりして構築を行うでしょう。
SASSは、プログラミングの知識があればより機能を活かしたコーディングを行うこともできます。

しかしながら、より大きく複雑なプロジェクトになれば、コードを体系的に書くことで効率性や機能性を高めることができます。
また、シンプルにすればするほど、ブラウザがコードを読み込む時間も早くなり、保守点検を行う際にもメンテナンスしやすくなります。

そうした点から、CSSを効率的に書くために、これまでもたくさんのメソッドが登場しました。

例えば、OOCSSは、コンテナーとコンテンツCSSオブジェクトで分けて記述しようとしてきました。
また、SMACSSと呼ばれる書き方では、CSSの記述ルールを5つのカテゴリーに分けることで書き方を簡素化しようとしました。
SUITCSSではUIコンポーネントを効率的に構築するために、構造的なクラス名を付けることを推奨してきました。
そして、以前ferretでも紹介したAtomic Designでは、粒度の段階を定めることで俯瞰して構築できるようにしていきました。

こうしたメソッドのどれを選んでみても、体系的な構造のCSSやUIの利点を活かすことは可能です。
制限が少なくより柔軟なフレームワークもあれば、簡単に理解でき、プロジェクトに採用しやすいものもあります。

それでもBEMが選ばれるのは、SMACSSほど初めてのひとでも困惑することなく、OOCSS以上に体系だった記述ができ、理解しやすい用語で説明できるからです。
そのようなわけで、ブロックを組み立てるように構築することから2009年の登場当初「レゴ」と呼ばれていたBEMが普及していったのです。

BEMとは何か?

それでは、BEMとは、一体どのようなものでしょうか。

BEMとは、「Blocks」(かたまり)「Elements」(要素)「Modifiers」(状態)の3つの頭文字を取ったもので、その名の通り3つの考え方をクラス名で体系的につけていく方法です。

bembem.png
BEMをもとに作成

Blockとは、独立した意味の塊で、もう少しざっくり言えば親要素となります。
Elementは、Blockの中に含まれるパーツのことで、Blockに対する子要素ということもできます。

Modifierは、BlockやElementに対するフラグのようなものです。
見た目や状態(disabledやfocus、highlightedやsize-bigなど)の情報を付け加えます。

例えば、以下の画像はGitHubのトップページキャプチャーですが、これをBlock・Element・Modifierに分けると、次のようになります。

git.png
BEMをもとに作成

BEMにおける命名規則

BEMでは、命名規則が明確に定義されているので、BEMを知っている人であればコードを見ただけでどれがどんなパーツになるのかが一目瞭然です。
裏を返すと、BEMを使うために命名規則を学ぶ必要があります。

しかしながら、BEMの命名規則は非常にシンプルです。
ここでは、Block・Element・Modifierのそれぞれの命名規則に関して確認していきましょう。

1. Block

block.png
Built on Pablo

Blockでは、それ自身で意味のある部品の名前をつけていきます。
Blockは入れ子にしたりお互いにインタラクションを起こしたりできますが、文法上は対等に扱います。
DOM表現(コントローラーやモデル)のない要素もブロックとして扱います。

● HTML

HTML要素は下記のようにクラス名が付けばBlockとします。

<div class=“block”>・・・</div>

● CSS

CSSでは、以下のように、HTML要素は付けずに、クラス名のセレクターだけにします。
タグ名やidを付けることもありません。

.block { color: #0060e6; }

2. Element

element.png
Built on Pablo

Elementは、Blockの中にあるもので、それ単体では意味のあるパーツにならないものを指します。
すべてのElementはBlockと紐づけて考えます。
Elementは通常、Blockの後ろに2つのアンダースコアをつけて命名します。

● HTML

Blockの中にあるHTML要素はすべてElementと考えます。
あるBlockの中では、すべてのElementは対等に扱います。

<div class=“block”>
  <span class=“block__element”>Home</span>
  <span class=“block__element”>Menu</span>
</div>

● CSS

Blockと同じように、クラス名のセレクターだけで書いていきます。
同じページ上の別のBlockやElementに依存してはいけません。

.block__element { color: #0060e6; }

以下のようにBlockと続けて書いたり、HTML要素の後ろに続けて書いてはいけません。

.block .block__element { color: #0060e6; } // ×
div.block__element { color: #0060e6; } // ×

3. Modifier

modifier.png
Built on Pablo

ModifierはBlockやElementのフラグのようなものです。
フラグをつけるには、BlockやElementの前にダッシュを2つつけて命名し、値がある場合はその後ろにもう一つダッシュをつけます。
「.block—modifier」のようにBlockにつくこともあれば、「.block__element--modifier」のようにElementにつくこともあります。

● HTML

Modifierはあくまでもオリジナル要素に対して色や大きさを変えるだけの役割を持っています。

<div class=“block block—mod”>
  <span class=“block__element block__element—modifier”>Home</span>
  <span class=“block__element”>Menu</span>
</div>

ただし、以下のようにModifierだけを単独でマーキングしてはいけません。

<div class=“block—modifier”>・・・</div> // ×

● CSS

Modifierも、CSSで記述するときには単独で書きます。

.block—modifier { color: #999; }

ただし、Modifierに関しては、BlockレベルのModifier付きの下にElementを書いてもいいことになっています。

.block—modifier .block__elem { color: #999; }

CSSをBEMで記述するメリット

1. 構造体系が明確化する

あるページにおいてBlockスタイルは他のElementと競合することはないので、構造体系が明確になります。
また、あるプロジェクトでBEMが出来上がれば、それをフレームワークのようにして他のプロジェクトで使い回すこともできるようになります。

2. 再利用とメンテナンス

さまざまな方法で独立したBlockを構築し、かしこく再利用することができれば、メンテナンスを行う必要のあるCSSコードの量が大幅に減ります。

まとめ

初めてBEMを見た人は、「ダッシュやアンダースコアが2個もあって美しくない」と感じるかもしれませんが、「堅固かつ流用可能で短く書けるCSS設計」として突き詰めていけばBEMが非常に効率的であることがわかります。

上記のような不満からBEMの書き方をカスタマイズして書く方法もありますが、グローバルスタンダードの書き方を覚えれば、他のフレームワークでBEMが使われていたときに構造を理解しやすかったり、共通言語となったりするので、正規の書き方は覚えておいて損することはありません。

ぜひBEMを使って効率的なCSSを構築していきましょう。