Sass で if文中で変数を使う時にスコープのトラップがあったのでメモ。
if文 ( @ifディレクティブ ) の中で作成された変数は、if文外でアクセスできない
次のような書き方だと変数が存在しないというコンパイルエラーになります。
.foo { @if $is-error { $color: red; } @else { $color: inherit; } color: $color; }
=> Undefined variable: "$color".
Sass の if文 ( @ifディレクティブ ) はスコープを作成するようで、ディレクティブ外の変数にはアクセスできるが、ディレクティブ内のローカル変数はディレクティブ外ではアクセスできないという仕様なようです。
if文で変数の変更したい時は、if文の外で変数定義をする必要がある
上記のような単純なものなら @else
節を使わずに書くのが良さそうです。
.foo { $color: inherit; @if $is-error { $color: red; } color: $color; }
或いは三項演算子のような if 関数を使う
.foo { color: if($is-error, red, inherit); }
おまけ global 変数の上書き
Sass v3.3 より前は、ローカルスコープ内で global の変数が変更できてしまっていた。
Sass v3.3 からはローカルスコープで global の変数は上書きされなくなった。
$color: red; .foo { $color: blue; color: $color; } .bar { color: $color; }
↓ Sass 3.3 より前でのコンパイル結果
.foo { color: blue; } .bar { color: blue; }
↓ Sass 3.3 以降でのコンパイル結果
.foo { color: blue; } .bar { color: red; }
global の変数をローカルスコープ内で上書き変更したい時は !global
キーワードを使う
$color: red; .foo { $color: blue !global; color: $color; } .bar { color: $color; }
↓ コンパイル
.foo { color: blue; } .bar { color: blue; }
こうすると、Sass 3.3 より前と同じ挙動になる。
ローカルスコープで global 変数を上書きしたい場合がチョット思いつかないけど…
ポエム
if文がスコープを作成するのは予想外だった。( Ruby もこうじゃないよね? )
SCSS で言うところの { }
で囲われるとスコープを作成する仕様になってるのかも知れない。
Sass v3.3 より前はローカルスコープで global の変数を上書きできてしまってたの、今のファイル分けまくって作成してる感覚だと結構ヤバイ仕様だったんだなーって思った。
[参考]
- 作者: 狩野祐東
- 出版社/メーカー: SBクリエイティブ
- 発売日: 2018/04/14
- メディア: 単行本
- この商品を含むブログを見る