SASSを使っていると「!default」という記述を見かけることがあります。
「!default」は@importや@useを使って変数を記述してあるファイルで非常に良く使用します。特に@useでは!defaultがないと次のようなエラーが発生することもあります。
Compilation Error
Error: This variable was not declared with !default in the @used module.
ここでは@importと@useそれぞれでの!defaultの使い方や、上記のようなエラーの原因と対処法について実例でまとめています。
!defaultとは何か?
「!default」とは、変数の値に設定することで、他のファイルで呼び出したときに、呼び出し元の!defaultを記載している変数の値の上書きを可能にするための記述です。
@importで呼び出すファイルの中で使われている場合と、@useや@forwardの中で呼び出したファイルの中で使われている場合で挙動が異なります。
!defaultの使い方(定義方法)
「!default」を使う時は、変数の値の末尾に記載します。
変数を値で定義している場合
$変数名: 値 !default;
変数をオブジェクト形式(キー名: 値)で定義している場合
変数をオブジェクト形式(キー名: 値)で定義している場合は( )の後ろに「!default」を記述します。
$変数名: ( キー名1: 値1, キー名2: 値2,,,, ) !default;
@importを使ったファイルの!default
node-sassの@importは既にサポートが終了し、今ではdart-sassの@useを使うことが推奨されています。とはいえ、現在でも過去の遺産として@importを使ってファイルを読み込んでいる場合は少なくありません。
そういった場合の「!defalut」の挙動について解説します。
@importを使ったときの!defaultの挙動
ファイルを@importを使って呼び出したときの「!default」の挙動は、@importが記述してある呼び出し先のファイルの中で、@importよりも上に同じ変数が定義してあれば、「!default」の値が置き換わります。
「!default」の指定がなければ、変数の値は置き換わらず、呼び出し元の値となります。
@importの位置が重要
@importを使って呼び出したファイルで!defaultの中の変数の値を上書きする場合は、@importの位置が非常に重要です。
変数が@importの上に記述されている場合は、「!default」の値が上書きされて置き換わり、「!default」がない変数の値はそのままになります。
変数が@importの下に記述されている場合は、「!default」の有無に関わらず変数の値が上書きされます。
挙動まとめ
「!default」の有無と、変数が@importよりも上と下のどちらに定義してあるかで、呼び出し元の「!defautl」のある変数の値がどうなるかをまとめると以下のようになります。
!defaultの有無 | 同じ変数が@impotよりも上か下か | !defaultのある変数の値 |
---|---|---|
あり | 上 | 上書きする |
なし | 上 | 上書きしない |
あり | 下 | 上書きしない |
なし | 下 | 上書きしない |
言葉の説明では難しいところがあるので、以下で実例を記載しておきます。
@importを使った!defaultの挙動実例
実例:!defaltあり、変数が@importよりも上にある場合
例えば以下のように「_colors.scss」というファイルの中に、「$theme-color」という変数と、その変数を使ったpタグの記述があるとします。
このとき、「$theme-color」の値の末尾に「!default」を記述します。
$theme-color: #333 !default;
p{
color: $theme-color;
}
このファイルを、「test.scss」というファイルの中に@importで読み込みます。その際、@importよりも上に「$theme-color: gold」として、変数を上書きする処理を記述しておきます。
$theme-color: gold;
@import 'colors';
.headline{
color: $theme-color;
}
このファイルをCSSにコンパイルすると以下のようになります。
↓ CSSにコンパイル
p {
color: gold;
}
.headline {
color: gold;
}
呼び出し元の「_colors.scss」の中に記述してあるpタグのcolorの値が、呼び出し先の変数の値で上書きされていることがわかります。
実例:!defaltなし、変数が@importよりも上にある場合
上記の例で、呼び出し元のファイル「_color.scss」の中で定義している変数「$theme-color」の値の末尾に「!default」が記述してない場合を見てみます。
$theme-color: #333;
p{
color: $theme-color;
}
このファイルを、「test.scss」というファイルの中に@importで読み込みます。
その際、先ほどと同じく、@importよりも上に「$theme-color: gold」として変数を上書きする記述を記載しておきます。
$theme-color: gold;
@import 'colors';
.headline{
color: $theme-color;
}
このファイルをCSSにコンパイルすると以下のようになります。
↓ CSSにコンパイル
p {
color: #333;
}
.headline {
color: #333;
}
@importしたファイルで「$theme-color: gold;」を指定しているにも関わらず、その値が無視され、@importしたファイルの「$theme-color: #333;」が適用されていることがわかります。
実例:!defaultの有無による違い(変数が@importよりも上にある場合)
!defaultの有無で、処理内容がどう変わるかをわかりやすくするため、!defaultがある変数とない変数をそれぞれ定義して、@importで呼び出す場合の例を記載しておきます。
例えば以下のように「_colors.scss」というファイルの中に、「$theme-color」という変数と、その変数を使ったpタグの記述があるとします。
このとき、「$theme-color」の値の末尾には「!default」を記述します。
更に、「$sub-color」という変数と、その変数を使ったdivタグを作成します。「$sub-color」には「!default」を記述しません。
$theme-color: #333 !default;
$sub-color: #777;
p{
color: $theme-color;
}
div{
color: $sub-color;
}
このファイルを、「test.scss」というファイルの中に@importで読み込みます。
その際、@importよりも上に「$theme-color: gold;」と「$sub-color: yellow;」を記述しておきます。
$theme-color: gold;
$sub-color: yellow;
@import 'colors';
.headline{
color: $theme-color;
}
.lead{
color: $sub-color;
}
このファイルをCSSにコンパイルすると以下のようになります。
↓ CSSにコンパイル
p {
color: gold;
}
div {
color: #777;
}
.headline {
color: gold;
}
.lead {
color: #777;
}
「!default」がついていた変数の値は上書きされたのに対し、「!default」がついていない変数の値は呼び出し元のファイルの値のままになっています。
実例:!defaultの有無による違い(変数が@importよりも下にある場合)
呼び出し先のファイルで、変数が@importよりも下に記載されている場合は「!default」の有無に関わらず変数、呼び出し元の変数の値は変化しません。
例えば以下のように「_colors.scss」というファイルの中に、「$theme-color」という変数と、その変数を使ったpタグの記述があるとします。
このとき、「$theme-color」の値の末尾には「!default」を記述します。
更に、「$sub-color」という変数と、その変数を使ったdivタグを作成します。
$theme-color: #333 !default;
$sub-color: #777;
p{
color: $theme-color;
}
div{
color: $sub-color;
}
このファイルを、「test.scss」というファイルの中に@importで読み込みます。その際、@importよりも下に「$theme-color: gold」「$sub-color: yellow;」として変数を上書きする記述を記載しておきます。
@import 'colors';
$theme-color: gold;
$sub-color: yellow;
.headline{
color: $theme-color;
}
.lead{
color: $sub-color;
}
このファイルをCSSにコンパイルすると以下のようになります。
↓ CSSにコンパイル
p {
color: #333;
}
div {
color: #777;
}
.headline {
color: gold;
}
.lead {
color: yellow;
}
@import元の「_colors.scss」の変数は!defaultの有無に関わらず、元々記載されていた値が適用されています。
一方、呼び出し先の「test.scss」に記述しているプロパティの値は、上書きした変数が適用されます。
@useを使ったファイルの!default
@useを使う場合は、呼び出し元のファイルの変数の上書きを許可するために「!default」の記述が必須となります。
上書きしようとしている変数に「!default」が記載されていない場合は、エラーが発生しコンパイルに失敗します。
▼「!default」を記述していない変数の値を上書きしようとしたときに発生するエラー
Compilation Error
Error: This variable was not declared with !default in the @used module.
@useを使ったファイルの!defaultの実例
実例:!defaultによる値の上書き
例えば以下のように「_colors.scss」というファイルの中に、「$theme-color」という変数と、その変数を使ったpタグの記述があるとします。
このとき、「$theme-color」の値の末尾に「!default」を記述します。
$theme-color: #333 !default;
p{
color: $theme-color;
}
このファイルを、「test.scss」というファイルの中に@useで読み込みます。
その際、変数「$theme-color」を上書きする処理を記述します。
@use 'colors' with ( $theme-color: gold );
.headline{
color: colors.$theme-color;
}
このファイルをCSSにコンパイルすると以下のようになります。
↓ CSSにコンパイル
p {
color: gold;
}
.headline {
color: gold;
}
呼び出し元の「_colors.scss」の中に記述してある変数「$theme-color」の値が指定したとおりに上書きされていることがわかります。
実例:!defaultがない場合はエラーになる
上記の記述で、呼び出し元のファイル「_colors.scss」の変数に「!default」をつけない場合は以下のようになります。
$theme-color: #333;
p{
color: $theme-color;
}
このファイルを、「test.scss」というファイルの中に@useで読み込みます。
その際、変数「$theme-color」を上書きする処理を記述します。
@use 'colors' with ( $theme-color: gold );
.headline{
color: colors.$theme-color;
}
このファイルをCSSにコンパイルすると以下のようなエラーが発生します。
↓ CSSにコンパイル
Compilation Error
Error: This variable was not declared with !default in the @used module.
╷
16 │ @use 'colors' with ( $theme-color: gold );
│ ^^^^^^^^^^^^^^^^^^^
╵
エラーメッセージで「Error: This variable was not declared with !default in the @used module.」と表示されます。
「エラー:この変数は、@usedモジュールで!defaultで宣言されていません。」というように、変数の値を書き変えたいなら「!default」を使ってねというメッセージが書かれています。
@forwardを使ったファイルの!default
@forwardを使う場合、基本的には@useを使うのと指定方法は同じです。
ただ注意しなければいけないのは、@forwardをしたときに変数の上書きをする場合、その変数の値に「!default」がないと、上書きできなくなるということです。
▼「!default」を記述していない変数の値を上書きしようとしたときに発生するエラー
Compilation Error
Error: This variable was not declared with !default in the @used module.
@fowardを使ったファイルの!defaultの実例
実例:!defaultによる値の上書き
例えば以下のように「_colors.scss」というファイルの中に、「$theme-color」という変数と、その変数を使ったpタグの記述があるとします。
このとき、「$theme-color」の値の末尾に「!default」を記述します。
$theme-color: #333 !default;
p{
color: $theme-color;
}
このファイルを、「_forward.scss」というファイルの中に@forwardで読み込みます。
その際、変数「$theme-color」を上書きする処理を記述します。ここでは上書きを許可するため値に「!default」も記載しておきます。
@forward 'colors' with ( $theme-color: blue !default);
このファイルを、「test.scss」というファイルの中に@useで読み込みます。
その際、変数「$theme-color」を上書きする処理を記述します。
@use 'forward' as colors with ( $theme-color: gold );
.headline{
color: colors.$theme-color;
}
このファイルをCSSにコンパイルすると以下のようになります。
↓ CSSにコンパイル
p {
color: gold;
}
.headline {
color: gold;
}
変数「$theme-color」の値が指定したとおりに上書きされていることがわかります。
実例:大本の!defaultがない場合はエラーになる(@forward時のエラー)
上記の記述で、「_colors.scss」の変数「$theme-color」の値に「!default」が無いは、@forwardで呼び出したときに変数の値に「!default」がないと、@forwardした時点でエラーが発生します。
$theme-color: #333;
p{
color: $theme-color;
}
このファイルを、「_forward.scss」というファイルの中に@forwardで読み込みます。
その際、変数「$theme-color」を上書きする処理を記述します。
@forward 'colors' with ( $theme-color: blue);
するとこの時点で以下のようなエラーが発生します。
↓ CSSにコンパイル
Compilation Error
Error: This variable was not declared with !default in the @used module.
╷
1 │ @forward 'colors' with ( $theme-color: blue);
│ ^^^^^^^^^^^^^^^^^^
╵
エラーメッセージで「Error: This variable was not declared with !default in the @used module.」と表示されます。
「エラー:この変数は、@usedモジュールで!defaultで宣言されていません。」というように、変数の値を書き変えたいなら「!default」を使ってねというメッセージが書かれています。
実例:大本の!defaultがない場合はエラーになる(@forwardに!defaultがある場合)
上記の記述で、「_colors.scss」の変数「$theme-color」の値に「!default」が無い場合でも@forwardで呼び出したときに変数の値に「!default」をつければ、@forward時点ではエラーは発生しません。
ですが、実際に変数を呼び出して、「_forward.scss」→「_colors.scss」と辿った時点でエラーが発生します。
$theme-color: #333;
p{
color: $theme-color;
}
このファイルを、「_forward.scss」というファイルの中に@forwardで読み込みます。
その際、変数「$theme-color」を上書きする処理を記述します。
このとき値の後ろに「!default」を記述しておけば、この時点ではエラーは発生しません。
@forward 'colors' with ( $theme-color: blue !default);
このファイルを、「test.scss」というファイルの中に@useで読み込みます。
その際、変数「$theme-color」を上書きする処理を記述します。
@use 'forward' as colors with ( $theme-color: gold );
.headline{
color: colors.$theme-color;
}
すると、「_forward.scss」→「_colors.scss」と辿り、CSSのコンパイルエラーが発生します。
↓ CSSにコンパイル
Compilation Error
Error: This variable was not declared with !default in the @used module.
╷
4 │ @use 'forward' as colors with ( $theme-color: gold );
│ ^^^^^^^^^^^^^^^^^^^
╵
実例:@forward時に!defaultがない場合は、@useで上書きできない
大本となる「_colors.scss」の変数「$theme-color」の値に「!default」が設定してあっても、@forwardで変数を上書きするときに、!defaultをつけず、かつ、@forwardを実行している「_forward.scss」を@useで呼び出したときに、変数の上書きをしようとした場合はエラーが発生します。
以下のように「_colors.scss」で変数「$theme-color」を定義するときに値に上書きを許可する「!default」をつけておきます。
$theme-color: #333 !default;
p{
color: $theme-color;
}
このファイルを、「_forward.scss」というファイルの中に@forwardで読み込みます。
その際、変数「$theme-color」を上書きする処理を記述します。値の後ろに「!default」を記述しません。
@forward 'colors' with ( $theme-color: blue);
この時点ではエラーは発生しません。
このファイルを、「test.scss」というファイルの中に@useで読み込みます。
@useで呼び出すときも、「$theme-color」を上書きしようとしなければエラーは発生しません。
ここではあえて、変数「$theme-color」を上書きする処理を記述します。
@use 'forward' as colors with ( $theme-color: gold );
.headline{
color: colors.$theme-color;
}
すると、@forwardしたときに変数の値の上書きを許可していないので、コンパイルエラーが発生します。
↓ CSSにコンパイル
Compilation Error
Error: This variable was not declared with !default in the @used module.
╷
4 │ @use 'forward' as colors with ( $theme-color: gold );
│ ^^^^^^^^^^^^^^^^^^^
╵