現時点でBEMによるCSS設計はベターだと思う。でもベストではない。
なにがベストに思わせないのかと言えば冗長的な命名方法。これだけ。
アンスコやらスラッシュが2連続くところが嫌すぎて困る。
というわけで。
BEMの命名方法をカスタマイズしてみる。
BEMの基本設計
BEMとは
- Block ⇒ 塊
- Element ⇒ 要素
- Modifier(keyとvalueで表す) ⇒ 状態(変化)
の事を言う。
BEM(ベム)と呼ぶようだが、某妖怪人間ではない。
参考:知っておきたいHTMLテンプレート設計法 - OOCSSの基本 | CodeGrid
BEMのお約束
- BlockとElementの区切りはアンスコ2個(__)
- BlockまたはElementとModifierの区切りはハイフン2個(--)
- ModifierのKeyとValueの区切りはアンスコ1個(_)
- BlockやElementを2つ以上の単語で表す時はハイフン1個(-)
.item {…}
.item-nav {…}
.item-nav__item {…}
.item-nav__item--state_active {…}
.item__body {…}
.item__body--state_active {…}
<section class="item">
<nav class="item-nav">
<a class="item-nav__item item-nav__item--state_active" href="#">タブA</a>
<a class="item-nav__item" href="#">タブB</a>
<a class="item-nav__item" href="#">タブC</a>
</nav>
<div class="item__body item-box__body--state_active">
…
</div>
<div class="item__body">
…
</div>
</section>
…アンスコやハイフンが2個続くのが嫌だ。分かりやすいけどクラス名も長い。
下記のように変更してみる。
#BEMの命名規則をカスタマイズしてみる
- BlockとElementの区切りはアンスコ1個(_)
- ModifierのKeyとValueの区切りはローワーキャメルケースで表わす。
- BlockとModifierまたはElementとModifierの区切りはハイフン1個(-)
- BlockやElementを2つ以上の単語で表す時はローワーキャメルケースにする(複合語の先頭を小文字で書き始める)
.item {…}
.itemNav {…}
.itemNav_item {…}
.itemNav_item-stateActive {…}
.item_body {…}
.item_body-stateActive {…}
<section class="item">
<nav class="itemNav">
<a class="itemNav_item itemNav_item-stateActive" href="#">タブA</a>
<a class="itemNav_item" href="#">タブB</a>
<a class="itemNav_item" href="#">タブC</a>
</nav>
<div class="item_body item_body-stateActive">
…
</div>
<div class="item_body">
…
</div>
</section>
…あれ?
カスタマイズした結果、3年くらい前と書き方がものすごく似ている。
違うとすれば<a>
にいちいちクラス付与しているところくらい。アンスコの意味合いも非常に似ている。
今はつなぎにハイフン使ってるけど、それはgoogleさんが推奨する書き方の一つだったからであって、さほどの意味は無い(というかハイフンって単語つなぎに使うから、違うように思っていたり)。
結局、自身が実務経験上編み出したCSS設計も「堅固で流用可能で短く書けるCSS設計」を目指していたわけで、突き詰めていくと似通ってくるのも当たり前と言えば当たり前。
とえいあえずはメモ書きなので、実装してみて内容を編集していこうと思う。
…と言っていた矢先。
実践 めんどうくさくない BEM - ダーシマ・ヱンヂニヤリング
ものぐさな私にぴったりなカスタマイズがあった。
わかる人には「ここはclass付与しても、ここは省略していいよ」で済むのだが、その一言では伝わらない人々を想定して書くのも勉強なので、時間見てまとめる予定。
更新履歴
2014.09.26追記
『Modifier』はマルチクラスで表わそうと考えていたが、こちらを変更する事にした。
理由としては、CSS内に記述された場合は.itemNav_item.stateActive {…}
みたいな書き方になるので、.itemNav_item
と一緒に記述された時のみ有効になるのでわかりやすい。
しかし、HTML側から見た場合はどうなるか?
.stateActive
というCLASS名はあちこちに出てくる可能性が高い。よく使う名前だと思う。だが『Active』と一口に言っても色々な『Active』が存在する訳で、それを一緒くたに.stateActive
で表わすのは乱暴すぎると思う。
冗長的にはなるが、HTMLから見た時は.itemNav_item-stateActive
というCLASS名の方が、どの要素に使えるか判断しやすい。
HTMLやCSSがデザイナーやコーダー内で完結できていればマルチクラスのままで良いと思う。
が、HTMLコーディングが完了した後、プログラマーの作業が発生するサイトの場合、プログラマーに対しての配慮が必要になる。
また、運用フェーズに入った時に、この書き方の方が膨大なCSSから検索がしやすく、対応時間を短縮する事も可能だ。
BEMの利点は、制作後の運用フェーズを考えた設計部分だと考えている。
命名方法については、ソースコードが長くなるので、冗長的な物はよくないと考える人も多いかもしれない。
だが、運用フェーズに入り、担当が変わった時の事を考えると、ある程度の察しがつく名称の方が引き継ぎがスムーズに行くと思う。