投稿日:2021年3月15日
@useはsassに新しく追加されたモジュール機能です。複数のモジュールの管理に頭を悩ませていた方は使用を検討してみましょう。
importの不便な点
2021年3月現在、useはDart Sassのバージョン1.23.0以降のみのサポートになっています。
残念ながらLibSassやRuby Sass環境の方はまだ利用できません…。アップデートを待ちましょう…。
まず以下のようにscssファイルを作成します。
外部から使用されることが前提となるスタイルシートはアンダースコアで始まるファイル名にします。アンダースコアで始まるファイル名のsassファイルはそれ自体はコンパイルされず、import、useで利用する前提のファイルになります。
$font_black: rgb(15, 20, 25);
@importでは以下の様にimportした変数はグローバルになるため以下のように使用できます。
@import "_sample";
.link {
color: $font_black;
}
変数がグローバルになることのデメリットとは何でしょう?
例えば以下のように大量にimportを抱えるスタイルシートの修正時にどこのモジュールを変更すれば良いのかわからなくなってしまったり、変数名が衝突したり、というデメリットがあります。
@import "_base";
@import "_widget";
@import "_layout";
.link {
color: $font_black; // この変数はどこに定義してある!?
}
それに対して@useにはnamespaceの概念があり、以下の様に使用することができます。
@use "sample.scss";
.link {
color: sample.$font_black;
}
モジュールのファイル名は_sample.scssですが、@useで使う場合はファイル名のアンダースコア(_)は無いものとして扱うことができるため"sample.scss"を指定しています。
ネームスペースは@useで指定したファイルのurlのファイル名から拡張子を除いた部分になります。この時、ファイル先頭のアンダースコアは外す必要があります。
ネームスペースはuse時にasで変更することができます。
個人的な意見ですが、後々スタイルシートの管理をする際に、ファイル名からネームスペースを推測するより、すべてのネームスペースがasで明示的に指定されているほうが楽だと思います。
@use "sample.scss" as s;
.link {
color: s.$font_black;
}
モジュールの変数の中には外部から利用される目的で定義していない変数もあると思います。そのような変数はprivateで定義して、意図しない利用法をあらかじめふせいでおくと良いでしょう。privateで定義された変数は外部から参照しようとすると、コンパイル時にエラーが出力されます。
Scssモジュールでは変数名の先頭をアンダースコア(_)またはハイフン(-)で始めることでその変数をprivateとすることができます。
$_hover_color: rgb(20, 20, 30); // private
$-transition_duration: 2s; // private
.link {
color: g.$_hover_color; // エラー
background-color: g.$_hover_color; // エラー
}
モジュールの変数の値は!defaultでその変数の値をデフォルト値として設定できます。デフォルトで定義された変数はimport時にwithで変更できます。
$font_black: rgb(15, 20, 25) !default;
$font_grey: #5b7083 !default;
$font_white: white !default;
$font_shadow: rgba($font_black, 0.5);
@use "../_generic.scss" as g with ($font_black: rgb(30,40,50), $font_white: #f0f0f0);
上の例では_sample.scssの$font_blackをrgb(30,40,50)、$font_whiteを#f0f0f0で上書きして使用しています。値を指定しなかった$font_greyはそのまま#5b7083として利用できます。
モジュールscssをどのプロジェクトにも転用できるような汎用的なものとして作成した場合には非常に便利ですね。
ただし、この機能は一歩間違えば定義箇所がバラバラになる悪魔のScssを生み出すきっかけになります。僕の意見では、!default、withの使用は可能な限り控えて@mixinの方を使用するほうが良い気がします。