BEMのmodifierでスタイルを切り替える時の書き方



## はじめに

BEMでこういうよくあるモジュールがあるとする。

```html
<div class="p-hoge">
  <div class="p-hoge__photo">
    <img src="aaa.jpg" alt="">
  </div>
  <div class="p-hoge__text">
    テキストテキスト
  </div>
</div>
```

modifierをつけて要素のstyleを切り替えたい、みたいなことはよくあると思う。

` .p-hoge <----> .p-hoge--reverse`

でも、sassはネストしまくると

- 可読性が悪い
- 検索しづらい

ので私も基本は、ネストさせないようにしている。
https://qiita.com/tatsuyankmura/items/49ac82183415b7779df1

その辺を踏襲しつつ、より良い書き方を探ってみることにした。


**※(注) BlockとElementをネストはさせないけど、modifierは「&」でネストさせます。
Block--Element まで検索出来れば、あとは見つけやすいだろうという考えです。**


## (A) それぞれスタイルを変化させるBlockとElementにModifierをつける

```html:A.html
<div class="p-hoge p-hoge--reverse">
  <div class="p-hoge__photo p-hoge__photo--reverse">
    <img src="aaa.jpg" alt="">
  </div>
  <div class="p-hoge__text p-hoge__text--reverse">
    テキストテキスト
  </div>
</div>
```

## (※参考)ネストさせて書くバージョン

```scss:A.scss

.p-hoge{
  display:flex;
  background-color:#f00;
  &--reverse{
    background-color:#00f;
  }
  &__photo{
    width:100px;
    &--reverse{
      order:1;
    }
  }
  &__text{
    font-size:1.5rem;
    &--reverse{
        order:0;
    }
  }
}

```

これは、楽！一人でやったり、短期の案件ならこれでいいんじゃないだろうか。


## ネストさせないで書くバージョン

```scss:A_2.scss

.p-hoge{
  display:flex;
  background-color:#f00;
  &--reverse{
    background-color:#00f;
  }
}
.p-hoge__photo{
  width:100px;
  &--reverse{
    background-color:#00f;
    order:1;
  }
}
.p-hoge__text{
  font-size:1.5rem;
  &--reverse{
    order:0;
  }
}

```

これは割とスムーズにかける。
「&」が使える分コードを書くのが楽だし ElementをBlockの入れ子にしてないので見やすい。
難点はhtmlの記述量が増えてしまうのと、「jsでclassを切り替えてstyle変更」が３つの要素を変更しなければいけないのが難点。
現実的ではないかも。

## (B) Aと似ているが、「Block + Modifier + Element」という点が違う

```html:B.html
<div class="p-hoge p-hoge--reverse">
  <div class="p-hoge__photo p-hoge--reverse__photo">
    <img src="aaa.jpg" alt="">
  </div>
  <div class="p-hoge__text p-hoge--reverse__text">
    テキストテキスト
  </div>
</div>
```

```scss:B.scss

.p-hoge{
  display:flex;
  background-color:#f00;
  &--reverse{
    background-color:#00f;
  }
}
.p-hoge__photo{
  width:100px;
}
.p-hoge--reverse__photo{
  order:1;
}
.p-hoge__text{
  font-size:1.5rem;
}
.p-hoge--reverse__text{
    order:0;
}

```

なんかうまい書き方が思い浮かばなかった。普通に書くのが無難か。


## (C) block要素にのみModifierをつける。 cssの方でネストにして対応
```html:C.html
<div class="p-hoge p-hoge--reverse">
  <div class="p-hoge__inner">
    <div class="p-hoge__photo">
      <img src="aaa.jpg" alt="">
    </div>
    <div class="p-hoge__text">
      テキストテキスト
    </div>
  </div>
</div>
```
```scss:C.scss

.p-hoge{
  $this: & !global;
  display:flex;
  background-color:#f00;
  &--reverse{
    background-color:#00f;
  }
}
.p-hoge__photo{
  width:100px;
  #{$this}--reverse &{
    order:1;
  }
}
.p-hoge__text{
  font-size:1.5rem;
  #{$this}--reverse &{
      order:0;
  }
}

```

ここでも、推奨されている
http://getbem.com/faq/#block-modifier-affects-elements
>While in general BEM recommends avoiding nested selectors, in this case they are reasonable.
>一般に、BEMはネストされたセレクタを避けることを推奨しますが、この場合は合理的です。


**thisをグローバルにせざるを得ないので、
案件で$thisは、この用途以外で使わない！というルールが必要。**

この書き方が一番いい気がする。

- jsでのclassの切り替えもblockだけで良い。
- ネストするけど、可読性は高い(Elementの)

最近はCで書いています。


もし、他に良い書き方があれば教えていただけるとありがたいです。


## 参考記事
https://qiita.com/tatsuyankmura/items/49ac82183415b7779df1
https://qiita.com/usagi-f/items/b4e56e765384c49d5d04
https://qiita.com/y_hokkey/items/70eb2bc1394d74989359