Edited at

今更ながらBEMについてと、それに対応するSassについてまとめてみる

More than 1 year has passed since last update.

今更ながらBEMについてのまとめです。

学習コストも低く、取り入れやすいので、勤めている会社でもこちらを使用しています。

以前は、BEMとMindBEMdingはわけて読んでいた気がしますが、今ではBEMといえばMindBEMdingという感じでしょうか?


BEMについて

BEMでは基本的にclassを使用します。

そして、クラス名は、Block, Element, Modifierの3つに分けて考えます。

Blockは全体を指すもので、その要素がElement、BlockとElementそれぞれの別バージョン(色違いなど)がModifierと呼ばれます。

具体例を見てしまった方がわかりやすいと思います。

<div class="media">

<div class="media__image">
<img src="" alt="" />
</div>
<div class="media__text">
<p class="media__title">タイトル</p>
<p class="media__lead">リード文</p>
</div>
</div>

記事の一覧などで、画像とタイトルなどが表示されているものを想像していただければと思います。

まず、mediaというBlock名をつけます。

あとはこれを元に、クラス名をつけていきます。

Elementは__(アンダースコア2つ)でつなぎ、Modifier--(ハイフン2つ)でつなぎます。

例えば、画像を表示する要素は、mediaというBlockのElement(要素)なので、media__imageとなります。

ただ、ここにはModifierがでてきていません。

仮に、「新着記事の場合、背景色を変えよう」などといった場合に、Modifierの出番です。

下記のようにします。

<div class="media media--new">

<div class="media__imageBox">
<img src="" alt="" />
</div>
<div class="media__textBox">
<p class="media__title">タイトル</p>
<p class="media__lead">リード文</p>
</div>
</div>

<div class="media media--new">以外は全く同じです。

ここでは、BlockのModifier(色違い)ですが、Elementの場合も同様に対応します。

media__titleの別バーションがあれば、media__title--○○となります。

ただし、可能な限りCSSに依存した名前はつけない方がいいです。

media--redとかにして、後から色が青に変わったら意味わからないことになります。

(css設計ではよく言われていることですが、これってとても難しいんですよね…)

また、ここはいろいろ意見があるところですが、僕はBlock__Element__Elementというような多重階層(?)は避けるようにしています。

各Elementは全てBlockの要素で、重要なのはこの親子関係と考えているからです。

では次に、これをSass(scss)で書いていきます。


Sass(scss)

まずセレクタを一通り書いてしまおうと思います。

こんな感じになります。

.media {

$block: &;

&--new {}

&__imageBox {}

&__textBox {}

&__title {
#{$block}--new & {}
}

}

好みがあるかもしれませんが、$block: &;のように、そのときの状態を変数にいれてしまうのが好きです。

常にやる必要は全くないですが、下記のような時はやった方がいいと思います。

例えば、新着記事(media--new)のとき、背景以外にもmedia__titleの見た目も変えて欲しいという要望があったとします。

下記のように<p class="media__title media__title--new">タイトル</p>とするのは、ちょっと嫌ですよね?

<div class="media media--new">

<div class="media__imageBox">
<img src="" alt="" />
</div>
<div class="media__textBox">
<p class="media__title media__title--new">タイトル</p>
<p class="media__lead">リード文</p>
</div>
</div>

では、これはやめてsass側で対応しようとします。

media--newの中にmedia__titleを入れてしまうと、media--new__titleになってしまうのでこれはダメです。

.media {

&--new {
&__title {}
}

&__title {}

}

では、&をやめて見ましょう。

こんな感じになります。

.media {

&--new {
.media__title {}
}

&__title {}

}

他にも、下記のように&を後ろにつけて、詳細度をあげる方法もあります。

.media {

&--new {}

&__title {
.media--new & {}
}

}

ただ、どちらも.mediaという部分が重複してしまいます。

変数に代入しても同じだろと思うかもしれませんが、これがいくつもでてくることになると違ってきます。

ということで、こういったときは変数にいれてあげるのがいいと思っています。


まとめ

今更ではありますが、BEMについてまとめてみました。

個人的にお伝えしたかったのは、Block__Element__Elementというような多重階層(?)は避けるようにしよう、scssは&を上手く使おうということでした。