CSS を Sass (SCSS) + BEM ( Block-Element-Modifier ) で書いているプロジェクトに参加してて、BEMに合うようにするために @at-root
を使ってくださいと言われ、 @at-root
というものを知らなかったので調べたメモ。
結論としては現在では Sass で BEM な CSS のセレクタを作るために @at-root
は必要なさそうです。 ( Ruby Sass v.3.5.6 で確認 )
超ざっくりした BEM 概要
Block__Element--Modifier
のフォーマットでクラスを書く。
状態ごとに別のクラス名になるから基本的にシングルクラスになる。
@at-root
@at-root
はネストを解除する
.foo { @at-root { .bar { color: #111; @at-root { .baz { color: #222; } } .qux { color: #333; } } } .quux { color: #444; @at-root { .corge { color: #555; } } } }
↓ コンパイル
.bar { color: #111; } .baz { color: #222; } .bar .qux { color: #333; } .foo .quux { color: #444; } .corge { color: #555; }
@at-root
内に書かれているものは、ネストがいくつ重なっていても無視してrootに配置されます。 (正直使いみちが謎…)
Sass (SCSS) で BEM なセレクタを書く
&
で文字列を結合してクラス名にする時は @at-root
は不要
.block { color: red; &__element { color: blue; &--modifier { color: yellow; } } }
.block { color: red; } .block__element { color: blue; } .block__element--modifier { color: yellow; }
@at-root
があっても BEM 的なセレクタにはなる
.block { color: red; @at-root { &__element { color: blue; @at-root { &--modifier { color: yellow; } } } } }
↓ コンパイル
.block { color: red; } .block__element { color: blue; } .block__element--modifier { color: yellow; }
歴史的経緯
ref. Sass 3.3で追加された「&」の新機能と@at-rootまとめ解説 | HTML5Experts.jp
@at-root
は Sass 3.3 で導入された。
Sass 3.2 の頃ネストさせて BEM 的なセレクタを作ろうとしてもエラーになっていた。
.block { &--modifier { ... } } // Sass 3.2 ではエラーになっていた
当時セレクタに文字列結合させるには #{&}
を使っていたが、この記法はネストさせると親セレクタが二重に出力されてしまう問題があった。
.block { #{&}__element { color: #333; #{&}--modifier { color: #444; } } }
↓ コンパイル
.block .block__element { color: #333; } .block .block__element .block .block__element--modifier { color: #444; }
※ 新しいSass Ruby Sass v.3.5.6
でも #{&}
で書くと同じように出力されます。
ネストしている親を出力しない @at-root
を使うと、上記の問題が解消された。
.block { @at-root { #{&}__element { color: #333; @at-root { #{&}--modifier { color: #444; } } } } }
↓ コンパイル
.block__element { color: #333; } .block__element--modifier { color: #444; }
どのバージョンからかは不明だが &
で直接セレクタの文字列結合ができるようになっているので、新しいSass (Ruby Sass v.3.5.6 で確認) では、@at-root
無しで直接 BEM 的な CSS が出力できるようになっている。
.block { &__element { color: #333; &--modifier { color: #444; } } }
↓ コンパイル
.block__element { color: #333; } .block__element--modifier { color: #444; }
SassでBEM的なCSSのセレクタを作るには、このような歴史的経緯があったようです。
@at-root
の使い方がイマイチ謎ですが、公式の例をみた感じ、@at-root
+ 関数 で使うのが一般的っぽい
@mixin unify-parent($child) { @at-root #{selector-unify(&, $child)} { @content; } } .wrapper .field { @include unify-parent("input") { /* ... */ } @include unify-parent("select") { /* ... */ } }
↓ CSS
.wrapper input.field { /* ... */ } .wrapper select.field { /* ... */ }
Sample
See the Pen Sass nest compile test by KIKIKI (@chaika-design) on CodePen.
ポエム
Sass の公式にある @at-root
の使い方みたいなのを見てもイマイチ使いみちがピンときていません…
個人受託してた時はずっとFLOCSS的な書き方をしていたので、BEMクラス名が長くてびっくりしてます。確かにクラス名を見れば状態がわかるので便利ですが。
あと、個人的に Modifier はマルチクラスで良いんじゃないのかなーってお気持ちがある。
[参考]
CSS設計に関して
- BEM を使うべき5つの理由(なぜ BEM が G.R.E.A.T といえるのか) - Frasco
- BEMによるフロントエンドの設計 - 基本概念とルール | CodeGrid
- BEMを参考にしたCSS設計 - Qiita
- OOCSS、BEM、SMACSS、FLOCSS、RSCSSを比較して自分にあった設計思想をみつける
Sass @at-root
- Sass: @at-root
- Sassで&を使ってネストするなら@at-rootを書かなくてもいい - Qiita
- Sass 3.3で追加された「&」の新機能と@at-rootまとめ解説 | HTML5Experts.jp
1冊ですべて身につくHTML & CSSとWebデザイン入門講座
- 作者: Mana
- 出版社/メーカー: SBクリエイティブ
- 発売日: 2019/03/16
- メディア: 単行本
- この商品を含むブログを見る