search
LoginSignup
12

More than 3 years have passed since last update.

posted at

updated at

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

はじめに

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

<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をつける

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>

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

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;
    }
  }
}

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

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

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変更」が3つの要素を変更しなければいけないのが難点。
現実的ではないかも。

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

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>
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の方でネストにして対応

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>
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

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
12