BEMとは
模写コーディングや実務において、クラス名をどうするか?という点で結構悩む方は多いのではないでしょうか??
適当にクラス名を付けたが為に、作業を進めていった時にクラス名がバッティングして、気付かずにコーディングを進めて悲惨な目に…なんてことにはなりたくないですよね。。
BEMとはCSSのクラス名を決定する際のルールであり、 Block Element Modifier の略になります。
BEMの命名規則
BEMではクラス名は次のように命名します。
.block__element--modifier
外側のコンテナとなる要素をblock
とします。
<div class="block">
<!-- コンテンツ -->
</div>
その中に入る各要素をelement
とします。
element
の先頭には__
アンダースコア2つを入れます。
<div class="block">
<span class="block__element"></span>
</div>
各要素の状態をmodifier
とし、block__element
クラスでベースとなるスタイルを定義し、block__element--modifier
クラスでは追加するスタイルを定義します。
modifier
の先頭には--
ハイフン2つを入れます。
<div class="block">
<span class="block__element block__element--modifier"></span>
</div>
実際に以前紹介したポートフォリオサイトを例に取ると、BlockとElementは以下のようなイメージです。
以上がざっくりとした説明になります。その他にもいくつかルールはありますが、これだけでもかなり管理しやすくはなりそうですね。
Block、Elementになる要素は…?
なんとなく命名規則はわかったけど何の要素をBlockにして、どの要素をElementにするねん!!という疑問が沸くと思います。
いちいちコーディングの都度、「えーとこの要素はブロック…?いやエレメントか?」等と考えていたのでは返って効率が悪くなってしまいます。
先にある程度の決め事をしておいて、迷いをなくしましょう!
以下、BEMの設計手法を踏まえた私なりのルールの紹介になります。
尚、BEMと相性の良いSCSSを用いて例を紹介してきます。
Blockでのルール
Blockとなる要素は、独立してどこにでも置くことができ、他のBlockには依存せません。
なのでBlockに対するCSSはトップレベルに書き、他のBlockを含むような書き方はしません。
次のようなSCSSはNGです。
.block {
.他のblock{}
}
HTMLの要素の配置としては、Blockを入れ子にするのはOKです。
次の例では、.main
ブロック内に.about
ブロックが入っていますが、このabout
ブロックはそのまま抜き出して違う場所に配置することが出来るようにします。
<main class="main">
<div class="main_inner">
<section class="about">
</section>
</div>
</main>
私がBlockとする要素は基本的には次の通りです。これ以外が出てきたらElementとします。※但し、<div>
はElementにもなります。
<header>
<footer>
<main>
<section>
<article>
<nav>
<aside>
<div>
Block部分のクラス名の例としては次の通りです。
要素 | クラス名(Block部分) | 用途 |
---|---|---|
header | header | サイトヘッダー |
footer | footer | サイトフッター |
main | main | メインコンテンツ |
nav | gnav | グローバルナビ |
section | 内容に応じて可変 | セクション |
Elementのルール
ElementはBlock中の構成要素になります。
Element部分のクラス名の例としては次の通りです。
要素 | クラス名(Element部分) |
---|---|
p | txt,ttl,btn |
div | inner,outer,wrapper,box |
hn | ttl |
table | tbl |
th | tttl |
td | tdat |
ul | list |
ol | list |
li | item |
dl | def |
dt | dttl |
dd | ddat |
figure | pic,fig |
Modifierのルール
Modifierは、既存のBlockやElementとベースとなるスタイルは同じだが、見た目や動きが少し異なるものを作りたい時に使います。
要素の状態等を表す、succes
、error
、large
、small
等のようなキーワードをModifierとします。
CSSとしては、ベースのスタイルとなる.block__element
クラスと、追加するスタイルの.block__element--modifier
クラスがそれぞれ用意され、要素に適用したい場合は、この2つのクラスを付与する事となります。
<div class="block">
<span class="block__element block__element--modifier"></span>
</div>
しかし、この様に書くとクラス属性の部分がやや冗長な感じになってしまいますので、私は以下のように書いています。
.block {
&__element {
/* block__elementのベースとなるスタイル */
&.--modifier{
/* block__elementクラスと--modifierクラスが付与されたときのスタイル */
}
}
}
block__element
はベースのスタイルとして、そこに--modifier
クラスも付与された時のスタイルを定義しています。
こうすることで、HTMLのクラス属性は次のように書く事ができます。
<div class="block">
<span class="block__element --modifier"></span>
</div>
この方がSCSSもHTMLも自然な感じに見えるので好みです。
BEMとSCSS
先に紹介した私なりのルールも踏まえてSCSSを書くと、次のようになります。
.block {
プロパティ: 値;
&__element1 {
プロパティ: 値;
}
&__element2 {
プロパティ: 値;
}
&__element3 {
プロパティ: 値;
&.--modifier {
プロパティ: 値;
}
}
}
上の様な形とする事で、ブロックで適用するスタイルが囲われて、コードが増えた時でも見やすくなります。
また、BlockやElementの名前を変更したくなった場合でも、変更箇所が少なくて済み、保守性もいいですね。
尚、出力されるCSSは次のようになります。
.block {
プロパティ: 値;
}
.block__element1 {
プロパティ: 値;
}
.block__element2 {
プロパティ: 値;
}
.block__element3 {
プロパティ: 値;
}
.block__element3.--modifier {
プロパティ: 値;
}
まとめ
BEM設計手法はとても素晴らしいものですが、これらの全てを正確に守る必要はありません。(案件を受けた時に指定があれば別ですが...)
スネークケース(アンダースコアを使う)のが嫌いだから、キャメルケース(単語の切れ目で大文字を使う)にする等、後から見た時に命名規則が誰の眼にもパッと分かりやすい事が重要です。
効率的なコーディングが出来るように心掛けましょう!!