調べればいくらでも記事は出てくるが自分用に整理する。
間違ったこと書いてたら遠慮なく突っ込んで下さい。
BEMについて
BEMは、Yandexという会社のフロントエンドチームが考えた開発手法で
- Block
- Element
- Modifier
の頭文字を取ったもの。
Block要素
BEMはこのBlockを基点にして命名される
Element
Blockを構成する要素。
Blockに対するElementってことで __
でつなぐ。
Modifier
BlockまたはElementのバリエーション違い、状態変化的なもの。
Modifierの関係にある場合は --
でつなぐ。
active
とかを付与するときは_
でつなぐ。
element
やmodifier
が2つ以上の単語で構成されるときは、-
でつなぐ。
以下例
<div class="block">
<div class="block__element"></div>
<div class="block__element block__element--modifier"></div>
</div>
<div class="block block--modifier">
<div class="block--modifier__element"></div>
</div>
.block{
width: 100px;
}
.block__element{
background: #fff;
}
.block__element--modifier{
background: #ddd;
}
.block--modifier{
width: 150px;
}
.block--modifier__element{
background: #f2f2f2;
}
のような感じになる。
BEMのデメリット
- 先程書いたhtmlやcssを見ると、class名が長くなってしまう
- 記述の仕方が独特なので、初見は気持ち悪さでいっぱいになる。
(アンスコ2つでつないだり、ハイフン2つでつないだり、ハイフン1つだったり何やねん....)
1点目に関しては、block
の名前を分かりやすく、かつ簡潔に書くことで解決できるかと。
(省略のしすぎは良くない。)
2点目に関しては、慣れ。
BEMのメリット
- 再利用性が高い
- 拡張性が高い
- メンテナンス性が高い
再利用性が高い
block
は独立した存在であり、スタイリングの基点になるので、コンテキスト(親要素のhtmlエレメントなど)に依存しない。
なのでページのどこに置いても基本的にはその機能を保つことができる。(他のcssに汚染されない)
拡張性が高い
開発が終了し、運用フェーズの段階で新たに色を変更する、幅を変更する必要が出てきた場合にmodifier
を付与することでバリエーションを増やすことが可能。
メンテナンス性が高い
これは1つめのものと被るかもしれないが、block
は独立しているものなので使い回すことが可能。
また、後からプロジェクトに参加した人でもhtmlのclass名を見るだけで、スタイルが予測しやすい。
最初にblock
を作成してしまえば、あとはblock
の組み合わせだけで新しいページを作成することも可能になる。
大規模なサイトになればなるほど、このメリットは大きくなると思う。
BEMを楽に書く
class名が長くなるのがデメリットだけれども、Emmet
やSass
,Stylus
を使えば、そこまで苦にならないはず。
Emmet
のBEMフィルタなんかは若干癖があるので全部をカバーはできないかもしれないが
.block>._element+._element--modifier|bem
.block.block--modifier>.block--modifier__element
htmlはこんな感じで展開すれば先に記述したhtmlと同一のものになる。
(もっと簡潔に書けるかもしれないが、bemフィルターが思い通りの出力をしてくれなかったので断念 orz)
先程のcssはsassを使用すると
.block{
width: 100px;
&__element{
background: #fff;
&--modifier{
background: #ddd;
}
}
&--modifier{
width: 150px;
&__element{
background: #f2f2f2;
}
}
}
のような感じで、特に@extend
とかを使用せずともスタイルを継承出来るので楽になる。
BEMとSassは相性イイネ。
厳密にBEMの命名規則にこだわる必要はないとは思うけれども、命名規則の参考になるのではないかと。
課題
Bootstrap
の命名規則はBEMではなくOOCSSを基準にしているので命名規則をBEMとした場合、htmlのclassにBEMとOOCSSの命名規則が混在することになるのでちょっと気持ち悪くなる。これのベストな解決策はまだ模索中。
とは言いつつ、bootstrapはcol-xs
などのグリッド関係のclassや、container
、form
系のclassしか使わないので、
逆に命名規則が違うことで見分けがついて良いのかなーと思っている。そこまで気にしていない。
前はbtn
やnav
なども頻繁に使用していたが、最近はこの辺もゴリゴリカスタマイズするようなデザインが多いので、
逆にbootstrap
側のスタイリングを殺すのが大変なので自分で書いてしまっている。
また、element_active
のようなものも、別にactive
だけで使用してもsassで入れ子で書くなり、&でつなげて書くなりすれば
他の部分を汚染するようなこともないと思います。むしろ、jsとかでいじるclassにjs-hogehoge
とかis-active
みたいなclassを付けたほうがhtml側で判断がつくので、それはそれでいいのかなーなんて思っています。