BEMでElement__Elementを許容するのを検討する

# 始めに
皆さんはCSSはBEMで書いていますでしょうか？僕は基本的にBEMを使っていて、Elementは1つのみに徹底して書いてきました。ただこの運用にするとあんまりに辛いなと思ってきてElementにElementを書いてもいいんじゃないかと思ってきました。

# 理想のBEM構成にした時の問題
例えばTODOリストをコーディングするときに、Blockとしてはリストとアイテムは分けておくと柔軟性が良くなるので以下のようにしておくのがベストです。リスト側でアイテム間のマージンを設定しておくと、アイテムだけのパーツは他の場所でも使いまわしやすくなります。

オンラインエディタで書いたものはこちらになります。
<p class="codepen" data-height="320" data-theme-id="0" data-default-tab="result" data-user="wintyo" data-slug-hash="QPXoKO" style="height: 320px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid black; margin: 1em 0; padding: 1em;" data-pen-title="Element2階層のBEMサンプル">
  <span>See the Pen <a href="https://codepen.io/wintyo/pen/QPXoKO/">
  Element2階層のBEMサンプル</a> by wintyo (<a href="https://codepen.io/wintyo">@wintyo</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

```pug:理想のBEM構成
//- リストのBEM
ul.todo-list
  //- アイテムごとのマージンをここで書く）
  li.todo-list__item
    //- アイテムのBEM（ここではマージンをかかない）
    .todo-item
      input.todo-item__check(type="checkbox")
      span.todo-item__text TODO
      button.todo-item__button 削除
  li.todo-list__item
    .todo-item
      input.todo-item__check(type="checkbox")
      span.todo-item__text TODO2
      button.todo-item__button 削除
  li.todo-list__item
    .todo-item
      input.todo-item__check(type="checkbox")
      span.todo-item__text TODO3
      button.todo-item__button 削除
```

```scss
// TODOリストのリスト部分のみ
.todo-list {
  padding: 0;
  
  &__item {
    & + & {
      margin-top: 10px;
    }
  }
}

// TODOリストの中身のみ
.todo-item {
  display: flex;
  align-items: center;
  width: 100%;
  padding: 10px;
  border: solid 1px #ddd;
  border-radius: 5px;
  
  &__text {
    flex: 1 1 0;
    padding: 0 5px;
  }
}
```

ただこの運用は明らかに冗長で、まとめてひとつのBlockにしたいときもあります。その場合、以下のように書いてしまうことがあります。

```pug:形式だけElement一つにする
ul.todo-list
  li.todo-list__item
    //- アイテムElementの後ろに名前を足して配下感を出す
    input.todo-list__item-check(type="checkbox")
    span.todo-list__item-text TODO
    button.todo-list__item-button 削除
  li.todo-list__item
    input.todo-list__item-check(type="checkbox")
    span.todo-list__item-text TODO2
    button.todo-list__item-button 削除
  li.todo-list__item
    input.todo-list__item-check(type="checkbox")
    span.todo-list__item-text TODO3
    button.todo-list__item-button 削除
```

```scss
.todo-list {
  padding: 0;
  
  &__item {
    display: flex;
    align-items: center;
    width: 100%;
    padding: 10px;
    border: solid 1px #ddd;
    border-radius: 5px;

    & + & {
      margin-top: 10px;
    }

    // itemエレメント以下で使っている感じを出す
    &-text {
      flex: 1 1 0;
      padding: 0 5px;
    }
  }
}
```

一応SCSSの階層関係を見るとElementの下に更に書かれそうだなという雰囲気は出てますが、単純に単語を連結したいのかの判断が難しくなります。

# Elementの中にElementを書くのを許容して明記させる
これを書くくらいだったらもう`__`をもう一つ増やしてElementの下に更にElementをはやしていることが分かるようにした方がいいかなと思いました。3つは流石にキツいのでブロックを分けましょう。

```pug:Elementの中にElementを書く
ul.todo-list
  li.todo-list__item
    //- アイテムElementの下で使うクラス名だと一目瞭然（もし違った書き方をしていたら指摘しやすい）
    input.todo-list__item__check(type="checkbox")
    span.todo-list__item__text TODO
    button.todo-list__item__button 削除
  li.todo-list__item
    input.todo-list__item__check(type="checkbox")
    span.todo-list__item__text TODO2
    button.todo-list__item__button 削除
  li.todo-list__item
    input.todo-list__item__check(type="checkbox")
    span.todo-list__item__text TODO3
    button.todo-list__item__button 削除
```

```scss

.todo-list {
  padding: 0;
  
  &__item {
    display: flex;
    align-items: center;
    width: 100%;
    padding: 10px;
    border: solid 1px #ddd;
    border-radius: 5px;

    & + & {
      margin-top: 10px;
    }

    // itemエレメント以下で使う設定
    &__text {
      flex: 1 1 0;
      padding: 0 5px;
    }
  }
}
```

# 終わりに
真面目にBEMで書いていくと、すぐにブロックを分ける必要がありました。Vue.jsとかだと同一ファイルに何個もブロックを書いても問題ありませんが、単純な静的サイトでscssファイルに書く場合はクラス名とファイル名は一緒になっていないと探しづらかったりするのでブロックの安易な分割は結構辛いなと思っていました。なるべくブロックを分割せずに上手くまとめようとすると謎のHTML構成になってしまい、修正が難しくなってしまうことも多々ありました。
そこで2階層までは`Block__Element__Element`で書けるようにして1つのブロックにまとめれるようになるともう少し保守がしやすくなるんじゃないかなと思いました。
ただこのようにかくと更に長くなるので、modifierが凄いことになるので、ここはマルチクラスに変えたりするといいのかなと思いました。
[BEM + RSCSSでVariant BEMを検討する](https://qiita.com/wintyo/items/4a9cfdbc6a5efc0031f3)