BEMについて整理
フロントのclass設計の中で出てくる「BEM」という概念について、かなり時間を使って調べたので、自分なりにまとめたいと思います。
これを調べるに至った経緯は、TECH:EXPERTの教材でBEMを推奨してまして、最終課題を取り組んでいる中、フロントのclass名を考えるのに時間がかかり、時間が勿体無いっ!と強く思った為です。
BEMは、CSSと密接に関わっていますが、ここではあくまで「BEM」がどういうものなのか、について書いていきます。
<BEMについて>
BEMはBlock、Element、Modifierの略語 で、
class名、id名をつける際の命名ルールであり、BEMのルールに沿ったclass名をつけることによって、コードの再利用性、長期メンテナンスをしやすくすることを目的としています。またBEMはCSSが組み立てやすくなるという特徴があります。
下記公式ドキュメント
BEMは
- Block ⇒ 塊
- Element ⇒ 要素
- Modifier(keyとvalueで表す) ⇒ 状態(変化)
の頭文字をとってもので、命名ルールの考え方に利用していきます。
デザインを実装しようと考えた時、まずblock(まとまり)を考えます。
画像では全体をhead blockと定義し、そのhead blockの中には、4つのBlockが存在しています。
※ここでは、head blockの構成要素として「4つの要素」があるのではなく、あくまでhead blockの中に、「4つの大きなBlock」が存在すると理解してください。
▼head (一番大きいブロック)
・menu (タブ)
・logo (logo画像)
・sign in (ログインするための機能)
・search (検索するための機能)
それぞれのブロックの中には、
▼menu
・tab1
・tab2
・tab3
・tab4
▼logo (logo画像)
・画像
▼sign in (ログインするための機能)
・ID 入力窓
・password 入力窓
・sign inボタン
▼search (検索するための機能)
・検索窓
・searchボタン
上記のような関係が成り立ち、これらは各Blockに対してそれぞれ構成「要素」があると考えてください。
改めて同じ画像載せます。
作る手順として、大枠から作るのが基本なので
▼header (一番大きいブロック)
・menu (タブ)
・logo (logo画像)
・sign in (ログインするための機能)
・search (検索するための機能)
↓
※わかりやすくここでは全てdivを使います。
<div class ="head">
<div class = "menu"></div>
<div class = "logo"></div>
<div class = "sign-in"></div> (2つの単語からできているのでハイフンでつなぐ)
<div class = "search"></div>
</div>
のようになります。
次に各ブロックの中身のElementを記載します。
▼menu
・tab1
・tab2
・tab3
・tab4
↓
(※上記ではdivを使いましたが、上記の場合一般的にはulとliを使う為、ここからはul、liを使います。)
<ul menu>
<li class = "menu__tab></div>
<li class = "menu__tab></div>
<li class = "menu__tab></div>
<li class = "menu__tab></div>
</ul>
となります。
上記はBlockである「menu」にElement要素である「tab」を「__(アンダーバー2つ)」で組み合わせたclass名をつけています。
さらにここで、もし「tab1にだけ色をつけたい」など個別で状態を変化させたい場合。
「Modifier(keyとvalueで表す) ⇒ 状態(変化)」が登場します。
<ul class = "menu"
<li class = "menu__tab></div>
<li class = "menu__tab></div>
<li class = "menu__tab></div>
<li class = "menu__tab></div>
</ul>
↓
<ul class = "menu">
<li class = "menu__tab menu__tab__color-red"></div>
<li class = "menu__tab></div>
<li class = "menu__tab></div>
<li class = "menu__tab></div>
</ul>
上記の
<li class = "menu__tab menu__tab__color-red"></div>
のclass名はそれぞれ
・menu__tab (Block__Element)
・menu__tab__color-red (Block__Element__Modifer-key)
上記の命名ルールに従って記載しています。
ここまでをまとめますと、
<div class ="head">
<ul class = "menu">
<li class = "menu__tab menu__tab__color-red"></div>
<li class = "menu__tab></div>
<li class = "menu__tab></div>
<li class = "menu__tab></div>
</ul>
<div class = "logo"></div>
<div class = "sign-in"></div> (2つの単語からできているのでハイフンでつなぐ)
<div class = "search"></div>
</div>
となりました。
他同様の流れで作成していきます。
改めてですがBEMは「命名ルール」であり、その「ルールに沿って作成したclass名」を「構成しているタグのclass名」に設置する。
<設置方法>
・タグの親子関係の親(ブロック)にはBlock名
・子(要素には)でにはBlock__Element 、状況に応じてBlock__Element__Modifer
が一般的です。
※注意
BEMの話で出てくる「Block」という単語と
htmlの構造の「ブロック」の話とは切り分けて考えてください。
html構造の場合、divが1:多の関係で、入れ子になっている場合は、「ブロック、要素」のような単語で区別するのではなく、「親と子」という単語で区別されることが多く、BEMの命名ルールに従って決めたclass名を、CSSとの関係を見ながら、親と子のclassに設定していくようなイメージ。
<ポイント>
「menu」「tab」 のように単語を見た時に、直感的にどこの部分のことを指しているかわかることが重要です。直感的に誰もがイメージしやすいというところがミソです。自分だけわかれば良いってものでもないです。
(「menu」「tab」勝手に命名していたものであり、「navi」と「link」のような直感的に誰でもわかるような名前であれば何でもいいです。)
<まとめ>
命名ルールはBEMだけではなく、他にも多数あります。
もちろん自分のように1つどのルールを利用するのか決めて、進めていくことも大事ですが、プロが作成したサイトのソースコード見ながら、一般的にメニューやボタンなどはどういったclass名をつけられがちなのか具体例をいくつも見て置くことも大事です。
上記はあくまで自分なりに調べて、まとめた内容ですので内容に誤りがある可能性もありますので、正確に知りたい方は公式ページへ!
参考記事