Edited at

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