BEMについてのメモ


調べればいくらでも記事は出てくるが自分用に整理する。
間違ったこと書いてたら遠慮なく突っ込んで下さい。

BEMについて

BEMは、Yandexという会社のフロントエンドチームが考えた開発手法で
- Block
- Element
- Modifier
の頭文字を取ったもの。

Block要素

BEMはこのBlockを基点にして命名される

Element

Blockを構成する要素。
Blockに対するElementってことで __でつなぐ。

Modifier

BlockまたはElementのバリエーション違い、状態変化的なもの。
Modifierの関係にある場合は --でつなぐ。
activeとかを付与するときは_でつなぐ。
elementmodifierが2つ以上の単語で構成されるときは、-でつなぐ。

以下例

html
<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>
css

.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名が長くなるのがデメリットだけれども、EmmetSass,Stylusを使えば、そこまで苦にならないはず。
EmmetのBEMフィルタなんかは若干癖があるので全部をカバーはできないかもしれないが

html(emmet)

.block>._element+._element--modifier|bem
.block.block--modifier>.block--modifier__element

htmlはこんな感じで展開すれば先に記述したhtmlと同一のものになる。
(もっと簡潔に書けるかもしれないが、bemフィルターが思い通りの出力をしてくれなかったので断念 orz)

先程のcssはsassを使用すると

scss
.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や、containerform系のclassしか使わないので、
逆に命名規則が違うことで見分けがついて良いのかなーと思っている。そこまで気にしていない。
前はbtnnavなども頻繁に使用していたが、最近はこの辺もゴリゴリカスタマイズするようなデザインが多いので、
逆にbootstrap側のスタイリングを殺すのが大変なので自分で書いてしまっている。

また、element_activeのようなものも、別にactiveだけで使用してもsassで入れ子で書くなり、&でつなげて書くなりすれば
他の部分を汚染するようなこともないと思います。むしろ、jsとかでいじるclassにjs-hogehogeとかis-activeみたいなclassを付けたほうがhtml側で判断がつくので、それはそれでいいのかなーなんて思っています。