5 LOG

いまどきのCSS – OOCSSとかBEMとかSMACSSとか

image

OOCSSとかBEMとかSMACSSとか、深く考え過ぎずに、気楽にいいとこ取りして、プロジェクトに合った使い方をしましょうって話。

重要なのはルールを決めること。

  • 命名ルールはBEMで(ただし厳密なBEMルールではなく、BEMっぽく)
  • シングルクラスよりマルチクラスを採用
  • idセレクタはCSSでは使わない

命名ルールはBEMで

BEMの命名ルールを取り入れる事で、CSSをBlock単位で考える事が出来るので、積極的にとりいれる

ただ、実際に書いてみるとわかるのだが、厳密なBEMのルールはめんどくさいし見た目が気持ち悪いので、ゆるくしたルールを決める。

Elementは「__」(アンダースコア2つ)、Modifierは「––」(ハイフン2つ)でつなぐ

これが命名ルールの基本。

Block、Element、Modifierを2つ以上の単語で表すときはキャメルケースをつかう

その方がぱっと見わかりやすい

.block-hoge__element-huga--modifier-piyoよりも

.blockHoge__elementFuga--modifierPiyoの方が見やすいから。
キャメルケースを使用することで、Elementをつなぐアンダースコアは1つでも良いかもしれないが、2つの方が見やすいので2つでつなぐ。

BEMの命名ルールは最初は違和感があるが、使っていくと、非常に良い命名方法だと実感できる。

ElementのElementは作らない

BEMで悩むポイントの一つが、Elementの中にElementがある場合どう命名するのか?
例えば

<article class="item">
    <header class="item__header"></p>
        <h1></h1>
        <p></p>
    </header>
    <div class="item__body">
    </div>
</article>

h1のclassは、.item__header__titleと書くのか?

この書き方にすると、さらにその中にElementがある場合とか、そんなクラス名は長過ぎて見たくもないので、.item__titleで良しとする。
厳密なBEMの解釈からすると.item__header__titleとする事で、階層を明確化出来るが、ゆるくしてしまう。「.itemというBlock内の要素」という事がわかればOKとする。

シングルクラスよりマルチクラスを採用

@extendを使えば、シングルクラスですっきり書く事が出来る。

例えばシングルクラスの場合

<article class="item">
    <header class="item__header"></header>
<div class="item__body"></div>
</article>
<article class="item--hoge">
    <header class="item--hoge__header"></header>
<div class="item__body"></div>
</article>
.item {
}
.item__header {
}
.item__body { 
}
.item--hoge {
    @extend .item;
    margin-bottom: 10px;
}
.item--hoge__header {
    @extend .item__header;
    background-color: #ccc;
    text-align: center;
}

と、@extendを使えば、シングルクラスですむ。
ただし、@extendの多用は書き出したCSSでセレクタが大量に並び、CSSの肥大化に繋がる。が、まあ、実際のところよほど大規模なサイトでは無い限り、そこまで考慮する必要は無い。

ではなぜマルチクラスか

例えば、上記のarticleをJavaScriptで使用する場合はどうするか?

1つには、JavaScript用のclass(.js_itemなど)を付ける方法がある。

しかし、.itemをモジュールとして考えると、例えば、.itemがスライドのモジュールである場合、スライドモジュールはCSSとJavaScriptで構成されるモジュールであるので、わざわざJavaScript用のclassを付ける必要は無い。最初からマルチクラスにしておいて、class="item item--hoge"として.itemをJavaScriptで使用すれば良い。
そうすれば、JavaScriptで.item__hogeを外したり.item--fugaを付けたりModifierを切り替えることが容易に出来る。

ちなみに、以前はJavaScriptで使用するセレクタにはJavaScript用に「js_」などのプレフィックスを付けたセレクタを用意していたが、CSS用のセレクタとJavaScript用のセレクタを別々で考える必要は無い。JavaScript用にidを付けることもあるが、idセレクタはCSSでは使用しないため、わざわざ「js_」などのプレフィックスを付ける必要も無い。

シングルクラスの方がすっきりするが、マルチクラスの方がJavaScriptにも対応出来、柔軟なので、マルチクラスの書き方に統一する。

マルチクラスにすることで、汎用的なCSSを使用することもアリとする。

idセレクタはCSSでは使わない

idセレクタをCSSで使用する必要性はない。
使用してはいけないわけではないが、特にたいしたメリットはなく、デメリットは大いにあるので、使用しないこととする。ただしJavaScript用に使用するのはOK。

以上、特に難しいルールでもないが、これだけでもCSSのメンテナンス性が飛躍的に上がります。
ただし、これがベストプラクティスというわけではない。

重要なのはルールを決めることである。

参考

実践 めんどうくさくない BEM
BEMという命名規則とSass 3.3の新しい記法
ぼくのかんがえたさいきょうのしーえしゅえしゅ