Sassの@useってなに?
こんにちは!ラブグラフ開発インターンのけいすけです。
Sassの@use
を知らなかったので調べてみました。
@use
とは
メンバー(変数、関数、ミックスイン)を他のSassファイルから読み込むための命令です。@use
を使って読み込まれたファイルはモジュールと呼ばれます。
例
foundation/_code.scss
foundation/_lists.scss
というモジュールがあるとします。
code {
padding: .25em;
line-height: 0;
}
ul, ol {
text-align: left;
& & {
padding: {
bottom: 0;
left: 0;
}
}
}
これらのファイルを読み込むには、次のように書きます。
ただし、アンダースコア、拡張子は必要ありません。
@use 'foundation/code';
@use 'foundation/lists';
次のコマンドを実行すると、
sass style.scss style.css
コンパイル後のCSSは次のようになります。
code {
padding: .25em;
line-height: 0;
}
ul, ol {
text-align: left;
}
ul ul, ol ol {
padding-bottom: 0;
padding-left: 0;
}
モジュールのメンバーにアクセスする
モジュールで定義されたメンバーにはそれぞれ次の書き方でアクセスできます。
- 変数:
<namespace>.<variable>
- 関数:
<namespace>.<function>()
- ミックスイン:
@include <namespace>.<mixin>()
<namespace>
はデフォルトではURLの最後の部分になります。
ただし、アンダースコア、拡張子は必要ありません。
例
$radius: 3px;
@mixin rounded {
border-radius: $radius;
}
@use "src/corners";
.button {
@include corners.rounded;
padding: 5px + corners.$radius;
}
コンパイル後のCSS
.button {
border-radius: 3px;
padding: 8px;
}
namespaceを変える
<namespace>
はデフォルトではURLの最後の部分ですが、@use "<url>" as <namespace>
と書くことで、namespaceを変えることができます。
例
$radius: 3px;
@mixin rounded {
border-radius: $radius;
}
@use "src/corners" as c;
.button {
@include c.rounded;
padding: 5px + c.$radius;
}
コンパイル後のCSS
.button {
border-radius: 3px;
padding: 8px;
}
メンバーをプライベートにする
-
または_
で始めるメンバーは、そのメンバーが定義されたモジュールでしかアクセスできなくなります。
例
$-radius: 3px;
@mixin rounded {
border-radius: $-radius;
}
@use "src/corners";
.button {
@include corners.rounded;
// エラー:$-radius は`_corners.scss`の外では使えない
padding: 5px + corners.$-radius;
}
!default
変数の定義の後ろに!default
と書くことで変数のデフォルト値を設定できます。変数にまだ値が割り当てられていない時のみ指定した値を割り当てます。変数に既に値が割り当てられている場合は、指定された値が代入されることはありません。@use <url> with (<variable>: <value>, <variable>: <value>)
と書くことでデフォルト値を上書きできます。
例1
$red: #f00 !default;
$border: 1px solid $red;
$text-shadow: 2px 2px $red;
code {
border: $border;
text-shadow: $text-shadow;
}
style.scss
で$red
のデフォルト値の#f00
を#800
で上書きしています。
@use 'library' with (
$red: #800,
);
コンパイル後のCSS
code {
border: 1px solid #800;
text-shadow: 2px 2px #800;
}
例2
例1だけだと変数の再代入との違いが分かりづらいと思ったので、もう一つ例をみてみましょう。
_library.scss
の内容は例1と同じです。
$red: #f00 !default;
$border: 1px solid $red;
$text-shadow: 2px 2px $red;
code {
border: $border;
text-shadow: $text-shadow;
}
style.scss
でwith ($red: #800);
を省いて、library.$red: #800
と書いてみました。
この場合、style.scss
の中では$red
の値は#800
になりますが、_library.scss
の中では$red
の値はデフォルト値の#f00
が使われます。
@use 'library';
library.$red: #800;
コンパイル後のCSS
code {
border: 1px solid #f00;
text-shadow: 2px 2px #f00;
}
変数への再代入
変数を定義した後で値を再代入できます。
例
$color: red;
@use 'library';
library.$color: blue;
@use 'library';
@use 'override';
@debug library.$color; //=> blue
パーシャル
_code.scss
のように_
で始まるファイルはパーシャルと呼ばれます。パーシャルはモジュールとしてのみ使われ、コンパイルされません。
Indexファイル
@use
でフォルダ名を指定した場合は、そのフォルダ内の_index.scss
または_index.sass
が読み込まれます。
例
code {
padding: .25em;
line-height: 0;
}
ul, ol {
text-align: left;
& & {
padding: {
bottom: 0;
left: 0;
}
}
}
@use 'code';
@use 'lists';
@use 'foundation';
コンパイル後のCSS
code {
padding: .25em;
line-height: 0;
}
ul, ol {
text-align: left;
}
ul ul, ol ol {
padding-bottom: 0;
padding-left: 0;
}
@import
の問題点
Sassには@import
という@use
と同様の命令が既にありますが、@use
は@import
が持つ問題を解決するために導入されました。@import
は数年後にSassから削除される予定で、今後は@use
を使うことが推奨されています。
@import
の問題点とは次のようなものです。
-
@import
は全てのメンバーをグローバルにしてしまう。これによってそれぞれのメンバーがどこで定義されたものなのか分かりづらくなってしまいます。 - 全てのメンバーがグローバルなため、ライブラリは名前の衝突を避けるためにプレフィックスをつけないといけない。
-
@import
で読み込まれたスタイルシートは読み込まれるたびに実行されるため、コンパイルに余計に時間がかかってしまう。 - プライベートなメンバーを定義する方法がない。
@import
との違い
-
@use
は現在のファイルでのみメンバーをアクセスできるようにする。グローバルスコープでアクセスできるようにはならない。 - namespaceによって各メンバーがどのモジュールで定義されているのかが分かりやすくなった。他のモジュールで定義されているメンバーと名前の衝突が起こる心配なく、短い名前を使えるようになった。
-
@use
はモジュールを一度だけ読み込む。間違って同じモジュールを複数回読み込む心配がない。 -
@use
はファイルの先頭に書かないといけない。ネストはできない。 - 1つの
@use
は1つのURLしか指定できない。
最後に
読んでいただきありがとうございました!@use
使っていきましょう!
参考
Discussion