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

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

More than 1 year has passed since last update.

はじめに

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

resistance_gowy
フロントエンド。 https://github.com/underground0930/ https://twitter.com/resistance_gowy http://resistance-underground.hateblo.jp/
https://htmlgo.site/
Why not register and get more from Qiita?
  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
No 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
ユーザーは見つかりませんでした