- MindBEMding – getting your head ’round BEM syntax – CSS Wizardry – CSS, OOCSS, front-end architecture, performance and more, by Harry Roberts
- BEM
- About HTML semantics and front-end architecture – Nicolas Gallagher
- block, element, modifierの頭文字
- Yandexで発案されたフロントエンドの命名手法
- CSSのクラス名に高い透明性を与え、他の開発者に意味を伝えやすくする
- 厳格で情報量が多いだけでなく、巨大なプロジェクトに適した命名規約である
- Nicolas GallagherがBEMを改良したものがベース
- 命名規約のパターン
.block{}
- 高レベルに抽象化されたもの、コンポーネント
.block__element{}
.block
をサポートする子孫をあらわす
.block--modifier{}
.block
の異なる状態をあらわす
- ハイフンやアンダースコアが1つではなく2つである理由
- ブロック名をハイフン区切りで表現できるようにするため
.site-search{} /* Block */
.site-search__field{} /* Element */
.site-search--full{} /* Modifier */
- BEMのポイントは、マークアップのパーツが名前だけで他の開発者により多くのことを伝えられるようにすること
- クラスのついたHTMLの断片を読むことでわかること
- それらの断片がどのように関係し合うか
- どれがコンポーネントなのか
- どれが、そのコンポーネントの子であり、エレメントなのか
- どれが、そのコンポーネントのバリエーションであり、Modifierなのか
- 例
.person{}
.person__hand{}
.person--female{}
.person--female__hand{}
.person__hand--left{}
- トップレベルブロック
person
がhand
などのエレメントを持つ person
はfemale
などのバリエーションを持ち、そのバリエーションがエレメントを持つ
- 例(通常のCSS)
.person{}
.hand{}
.female{}
.female-hand{}
.left-hand{}
- 意味はわかるが、分断されているものもある
.female
とは何か?.hand
とは時計の針のことか?カードゲームのハンドか?
- BEMを使うことでより説明的で明示的になれる
- 名前だけでいくつもの要素を関連付けることができてパワフル
前述のsite-search{}
を通常の命名にした場合。
<form class="site-search full">
<input type="text" class="field">
<input type="Submit" value ="Search" class="button">
</form>
クラスはゆるい繋がりで、何も伝えてはくれない。これでも作業は可能だが明瞭ではない。 BEMを使った場合はこうなる。
<form class="site-search site-search--full">
<input type="text" class="site-search__field">
<input type="Submit" value ="Search" class="site-search__button">
</form>
site-search
というブロックがあり、.site-search__field
と呼ばれる要素を含んでいることが見て取れる。.site-search
のバリエーションである.site-search--full
があることもわかる。
他の例を見てみよう。
OOCSSを知っていれば、メディアオブジェクト(the media object)に馴染みがあるだろう。BEMのやり方では、メディアオブジェクトはこうなる。
.media{}
.media__img{}
.media__img--rev{}
.media__body{}
このようにCSSを書くことで.media__img
と.media_body
が.media
に含まれるということと、media__img--rev
が.media__img
のバリエーションであることがわかる。それらの情報はCSSのセレクタ名だけで得ることが出来る。
別な利点もある。これもメディアオブジェクトの場合だ。
<div class="media">
<img src="logo.png" alt="Foo Corp logo" class="img-rev">
<div class="body">
<h3 class="alpha">Welcome to Foo Corp</h3>
<p class="lede">Foo Corp is the best, seriously!</p>
</div>
</div>
上記を見ても、.media
と.alpha
が互いにどう関係するのかはわからない。
.body
と.lede
や、.img-rev
と.media
はどうだろう?
このHTMLからは、コンポーネントが何で構成されていて、どれがオプションなのかは読み取れない。
BEMで書き換えるとこうなる。
<div class="media">
<img src="logo.png" alt="Foo Corp logo" class="media__img--rev">
<div class="media__body">
<h3 class="alpha">Welcome to Foo Corp</h3>
<p class="lede">Foo Corp is the best, seriously!</p>
</div>
</div>
以下のことがわかる。
.media
はブロック.media__img--rev
は.media
のエレメントでありモディファイアを持っている.media__body
は.media
のエレメントでありモディファイアを持っていない これらはすべてクラス名であり、とても有用だ。
- BEMに対する反論の多くは、それが醜いということ
- 純粋なコードの見た目を理由にBEMを避けようというのであれば、あなたは要点を理解していないと言わざるをえない
- コードがメンテしづらい状態(または本当に読むのが難しい状態)になるのであれば、それを使う前によく考える必要があるが、単に見た目が奇妙になるだけで、妥当な目的があるのであれば、それを使わないと考える前によく検討すべき
- BEMの見た目が奇妙なのは認めるが、それがもたらすパワーは、見た目に関するどんなネガティブ要素よりも桁違いに大きいと思う
- BEMはちょっとおかしく見えるし、入力の手間も余計にかかるが(たいていのエディタにはオートコンプリートがあるし、ファイルサイズはgzip圧縮で解消される)、ほんとにパワフルだ
BEMを使う場合、すべてに適用する必要はないということを憶えておこう。
.caps{ text-transform:uppercase; }
このCSSはどのBEMカテゴリにも属さない標準的なルールだ。 そうでない非BEMルールはこれ。
.site-logo{}
ロゴの指定だ。BEMっぽくすることもできる。
.header{}
.header__logo{}
しかし、こうする必要はない。
別な例。
<div class="content">
<h1 class="content__headline">Lorem ipsum dolor...</h1>
</div>
Here we might be able to just call the second class .headline; it depends on if it is styled that way because it’s in .content, or whether it just happens to live in .content. If it is the latter then we do not need BEM.
Everything is potentially open to moving into BEM territory, though. Taking our .site-logo example again, imagine that we want to have a festive version of the logo for our Christmassy site design. We could have:
.site-logo{}
.site-logo--xmas{}
We can quickly build variations of things by using the -- modifier notation.
One of the hardest parts of BEM is deciding when to start and stop scope, and when (or not) to use it. It’s a case of ‘you’ll just know when you know’.
So that’s BEM (or a slight variation thereof); a highly useful, powerful and simple naming convention to make your front-end code easier to read and understand, easier to work with, easier to scale, more robust and explicit and a lot more strict.