Help us understand the problem. What is going on with this article?

少し細かいBEMい話

More than 3 years have passed since last update.

BEMってむずかしい?

2014年はたくさんのサイトでBEM 、もといBEMな命名規則が採用されたのではないかとおもってます。(拙著でも取り上げてます。)

しかし、実際に導入されているサイトのコードをみてみると、んー、と感じることがあったり、または周りの開発者が、BEMむずかしい、といってるのを聞くことがある。

「これで合ってるの?」

むずかしい、と感じるのはたぶんBlockElementとの関係やバランス、あとはクッソ名前が長くなってしまうことの不安にあるのではないかと考えてます。

例えば、ふとこのQiitaの記事ページのサイドバーにある、関連投稿モジュールをみてみましょう。

関連投稿

これをどうマークアップするか、どういうセレクタを書くかっていうのは人やプロジェクトによって全然違うし、このパターンがQiitaの中でどのくらい・どのように存在するかで変わります。

ただBEMを意識しはじめたことだと、次のように書くかもしれません。すごい極端な例。

<div class="widget">
  <h3 class="widget__title">関連投稿</h3>
  <ul class="widget__list">
    <li class="widget__list__item">
      <a href="#author" class="widget__list__item__author">
        <img src="author.png" alt="auhtor" class="widget__list__item__author__avatar">
      </a>
      <a href="#post" class="widget__list__item__title">
        記事のタイトル
      </a>
    </li>
    <li class="widget__list__item">
      ...
    </li>
  </ul>
</div>

かなり簡素化したHTMLですけど、このWidgetモジュールを構成するツリーをそのままBEMっぽいツリーにしようとすると、こう考えてしまう人はいるかもしれません。

これに対し、次の2点を考えます。

  • ElementのElementは冗長になっている
  • モジュールとしての単位が大きすぎる

モジュールを分解する

先ほどのHTMLに手を加えるならば、僕の場合はこうするだろうってのは次のような形です。
(しれっとちょっとdivは追加してる)

<div class="widget">
  <h3 class="widget__title">関連投稿</h3>
  <ul class="list">
    <li class="list__item">
      <div class="media">
        <a href="#author" class="media__image avatar">
          <img src="author.png" alt="auhtor">
        </a>
        <a href="#post" class="media__body">
          記事のタイトル
        </a>
      </div>
    </li>
    <li class="list__item">
      ...
    </li>
  </ul>
</div>
  • widget
  • list
  • media
  • avatar

ちょっと細かめに割っていますが、パターンが増えてくる・見えてくると、こういった形になるのではないかと思います。実際にはもっと複雑で、ユニークなデザインが来るので、こんなにすっきりした形にはならないことも多いですが、設計イメージはこんな感じです。

分解できないとすれば?

前述のとおり、分解したって再利用も無いなーみたいなことも多く、そうすると下手に分割をしてもあまり意味ないこともあります。しかし、その場合にもElement__Elementみたいな命名にはならないようにします。

今度も元のHTMLのいじるならこう。

<div class="widget">
  <h3 class="widget__title">関連投稿</h3>
  <ul class="widget__list">
    <li class="widget__listItem">
      <a href="#author" class="widget__listItemAuthor">
        <img src="author.png" alt="auhtor" class="widget__listItemAvatar">
      </a>
      <a href="#post" class="widget__listItemTitle">
        記事のタイトル
      </a>
    </li>
    <li class="widget__listItem">
      ...
    </li>
  </ul>
</div>

何が違うかっていうのは、このモジュールのBlockであるwidgetに対するElementの考え方です。

元のHTMLの場合、ツリーを意識しすぎて、どんどんElementにしてしまっていたのですが、改めた方では、ルートであるBlockのwidgetにぶら下がるようにしています。

widget__listItemAvatarこれは、

ウィジェットの、リストの、アイテムの、アバター...

ではなく、

ウィジェットの、リストアイテム内のアバター

って感じです。(わかりづらそう

まとめ

なんでこんなこと書いてみたかというと、CodeGridの@geckotang氏のCSSConfレポートでも報告があったんですが、CSS設計セッションの中で紹介されてたコード例で、

.main-header__nav-list__link {
  ... same stuff ...
}

ってのがあって、「ありゃ、そんな名前にするの?」とか思ったからです。(CodeGridの記事の中で、おなじような話を@geckotangが書いているので、読める方はぜひ)

解説したコードが別に正解ってわけでもないですが、Element__Elementなパターンに遭遇したら、立ち止まって考えてみてはいかがでしょーか。

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away