BEMの命名規則は賢い

2014-01-23

BEMおよびその命名派生としてのMindBEMdingで使われるfoo__barfoo--barというようなハイフン、アンダースコアを重ねた命名はキモいし冗長だと嫌われがちだ。僕自身も初見ではそのように思っていた。しかしこれは本当に良いアイデアだと思うし、実務でも僕は採用している。

CSSの設計、その命名のときに考えるのは、それがいかに明白であるかということと、汚染されるリスクを抑えられるか、ということだ。ワードを明確に区切ることによって、その機能・カテゴリを区別するという点においては、別に単一記号であろうが、キャメルケース、スネークケースであろうがなんでもいいかもしれない。しかしスタイルが汚染されるリスク、という点でこの珍妙な命名は優秀だ。

プロジェクトに関わる開発者が多いほど、その書き方にブレは生じる。もちろんコーディング規約なり、スタイルガイドなりであらかじめルールを共有しておけば、というのは前提にあるとしても、それが100%守られる保証はない。少なくとも自分の経験上残念ながら無い。

ここで仮にBEMのようなElement,Modifierといった概念を継承しつつも、foo__barfoo--barといったのが冗長でキモいという理由で、’foo_bar’や’foo-bar’のような命名を採用したとしよう。

.widget { ... }
.widget_title { ... }
.widget-sidebar { ... }

なんてことはないと思えるが、ハイフンやアンダースコアといった記号はBEM的な前提ルールを無視して使われてしまう可能性が高い。それは単純に単語を区切りたいというような理由でだ。

.widget { ... }
.widget_title { ... }
.widget-sidebar { ... }

.contact-form { ... }
.price-table { ... }

単語を区切りたい場合にはpriceTableのようなキャメルケースで!というルールを用意すれば、というのもあるかもしれないが、やはり守られる保証はない。ところが、単語を区切りたいだけという理由でfoo__barfoo--barのように書こうとする開発者はまずいない。少なくとも単一で使われるよりは少数だろう。つまりは設計上のルールとして定義するfoo__barfoo--barといったルールは、そうでない記法よりもそのルールが破壊されるリスクが少ないと考えている。

そしてこの冗長な命名から少しでもタイプ数を減らすためアイデアもある。それはVigetの記事MCSSのModifierの記法にある。

// in Sass
.widget { 
  &.-sidebar { ... } // Viget
  &.__sidebar { ... } // MCSS
}
/* in CSS */
.widget.-sidebar { ... } // Viget
.widget.__sidebar { ... } // MCSS
<!-- in Markup -->
<div class="widget -sidebar">Viget</div>
<div class="widget __sidebar">MCSS</div>

これらがより良いアプローチであるということではないが、ひとつのアイデアだ。 ちなみにいずれも今回フォーカスする箇所が本題ではないので、設計のアプローチのアイデアとしてそれぞれ一読をおすすめする。なおVigetの記事で参照されているが、ハイフン2つからはじまるセレクタはダメなようだ。これについては詳しく追ってない。

BEMのこうした命名に関しては、結論好きなように書けばいい、という話ではあるものの、そこにどういった利点があるかというのを一考してみるも良いのではないかと思う。

Hiroki Tani

Twitter | GitHub

Front-end Engineer, Writer & Speaker