はじめに
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をつける
<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>
(※参考)ネストさせて書くバージョン
.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;
}
}
}
これは、楽!一人でやったり、短期の案件ならこれでいいんじゃないだろうか。
ネストさせないで書くバージョン
.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」という点が違う
<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>
.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の方でネストにして対応
<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>
.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