上位のmodifierから下位のelementを上書くときに名前を省略したい
※この記事はSCSSでBEMスタイルのコーディングをすることを前提としている。
最近のSassでは、&をクラス名に使うとコンパイル後にセレクタを外出ししてくれる便利な機能がある。
sample.scss
// blockクラス
.my-class {
// デフォルトのスタイル
&__body {
// 本文elementのスタイル
}
// 強調アレンジの為のmodifierクラス
&--emphasis {
// ここにelement上書きのスタイルを実装(※)
}
}
ここで(※)の部分に注目する。
modifierの内側でも&__body
の型でelementを指定したくなるが、この部分で&
を使うとイメージとは異なる結果になってしまう。
sample.scss
.my-class {
// デフォルトのスタイル
&__body {
// 本文スタイル
}
// 強調アレンジの為のmodifier
&--emphasis {
&__body {
// .my-class--emphasis .my-class__body というルールにしたい(☆)
}
}
}
上記をコンパイルすると、「☆」部分のセレクタは、
.my-class--emphasis .my-class__body
ではなく
.my-class--emphasis__body
となってしまい、思った通りにならない。
(そういう仕様だから当たり前なんだけど)
block名直書きは恰好悪い…
直にblock名を書いてもよいが、せっかく他では&
を使っているのになんか気持ち悪い。
sample.scss
.my-class {
// デフォルトのスタイル
&__body {
// 本文スタイル
}
// 強調アレンジの為のmodifier
&--emphasis {
.my-class__body {
// せっかく&で省略できたのに恰好悪い
}
}
}
block直下で&
を変数に格納して解決
そこで、適当な変数に&
を格納すると上手くいく。クラス名として使うにはインターポレーションが必要になる。
sample.scss
.my-class {
// $thisに".my-class"を格納する
$this: &;
// デフォルトのスタイル
&__body {
// 本文スタイル
}
// 強調アレンジの為のmodifier
&--emphasis {
#{$this}__body {
// 本文の上書き
}
}
}
変数名は$this
・$and
・$self
など気にいったものを使えば良い。筆者はなんとなくJSっぽくなるので$this
を使っている。プロジェクト全体で名前を統一し、必ずBlockクラスの直下で定義するようにした方が良いだろう。