Skip to content

Instantly share code, notes, and snippets.

@juno
Last active April 11, 2024 05:50
Show Gist options
  • Star 86 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save juno/6182957 to your computer and use it in GitHub Desktop.
Save juno/6182957 to your computer and use it in GitHub Desktop.
Summary of http://csswizardry.com/2013/01/mindbemding-getting-your-head-round-bem-syntax/ エッセンスだけ訳。翻訳の正しさは微妙。

MindBEMding

BEMとは?

  • block, element, modifierの頭文字
  • Yandexで発案されたフロントエンドの命名手法
  • CSSのクラス名に高い透明性を与え、他の開発者に意味を伝えやすくする
  • 厳格で情報量が多いだけでなく、巨大なプロジェクトに適した命名規約である

MindBEMding

  • 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{}
      • トップレベルブロックpersonhandなどのエレメントを持つ
      • personfemaleなどのバリエーションを持ち、そのバリエーションがエレメントを持つ
    • 例(通常の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にすべきか、やめるべきか

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment