SASSのモジュール
この記事ではSASSのモジュールについて説明します。
@use と @forward を使って SASS をモジュール化し、変数、ミックスイン、関数、テーマ設定、公開API を再利用する方法を解説します。
YouTube Video
SASSのモジュール
SASSのモジュールシステムはスタイルを明確にスコープ化し、再利用しやすく保守しやすい設計を実現します。
モジュールの基本的な考え方
SASSモジュールは、以前の @import が抱えていたグローバル汚染や依存関係が分かりにくいという問題を解消します。各ファイルはモジュールとして名前空間付きで読み込まれ、外部に公開した項目だけを他のファイルから参照できるようになります。
ファイル構成の例
まずは現実的なプロジェクト構成を示します。以下は小さめのデザインシステムの例です。
1styles/
2├─ _variables.scss
3├─ _mixins.scss
4├─ _functions.scss
5├─ components/
6│ ├─ _button.scss
7│ └─ _card.scss
8├─ utilities/
9│ └─ _helpers.scss
10└─ main.scss- この構成はモジュール化しやすく、テストや差し替えも簡単になります。
- 部分ファイルは先頭にアンダースコアをつけます。
@use の基本
@use はモジュールを読み込んで名前空間を提供します。名前衝突を防ぎ、どのモジュールから来たかが明確になります。
1// _variables.scss
2$primary-color: #0a74da;
3$padding-base: 12px;- このファイルは、変数だけを置くシンプルなファイルです。モジュールで公開される変数はそのまま
@useで参照します。
1// main.scss
2@use 'variables';
3
4.example {
5 color: variables.$primary-color;
6 padding: variables.$padding-base;
7}variablesモジュールをvariables.名前空間で参照しています。これによりどのモジュール由来かが明確になります。
名前空間を短くする/別名をつける
as を使うと名前空間を短くできます。
1@use 'variables' as vars;
2
3.btn {
4 color: vars.$primary-color;
5}variablesを短くしたvarsという名前で読み込む例です。読みやすさと入力のしやすさのどちらを優先するかによって適切な名前を選びます。
ミックスインの定義
ミックスインや関数もモジュールの中で定義して利用できます。コメントは、プロジェクトの規約に合わせて統一するとわかりやすくなります。
1// _mixins.scss
2// Create a simple responsive container mixin
3@mixin container($max-width: 1200px) {
4 width: 100%;
5 margin-left: auto;
6 margin-right: auto;
7 max-width: $max-width;
8}- このファイルでは、コンテナ用のミックスインを定義しています。引数を受け取りデフォルト値を持たせています。
1// main.scss
2@use 'mixins' as m;
3
4.wrapper {
5 @include m.container(1000px);
6}- ミックスインを
@includeで使用する例です。
関数の定義
関数は値を返す目的で使用され、モジュール内で定義して再利用できます。デザイン値の計算処理などを関数化すると、スタイルが安定しメンテナンスしやすくなります。
1// _functions.scss
2@use 'sass:math';
3
4// Create a simple px-to-rem converter function
5@function to-rem($px, $base: 16) {
6 @return math.div($px, $base) * 1rem;
7}- このファイルでは、ピクセル値をremに変換する関数を定義しています。デフォルトの基準値も指定しています。
1// main.scss
2@use 'functions' as f;
3
4.title {
5 font-size: f.to-rem(24);
6}- 関数を
@use経由で呼び出し、計算結果をスタイルに適用する例です。
モジュールの公開と @forward(API設計)
複数の内部ファイルをまとめて外部に公開したいときは、@forward を使って「公開API」を作れます。
1// _index.scss (module entry)
2@forward 'variables';
3@forward 'mixins';
4@forward 'functions';- 内部の複数ファイルをまとめてひとつのエントリポイントとして扱い、そこから公開用のAPIを提供します。こうすることで、利用する側はそのエントリポイントだけを読み込めば必要な機能をすべて使えるようになります。
1// main.scss
2@use 'index' as ds; // ds = design system
3
4.button {
5 color: ds.$primary-color;
6 @include ds.container();
7}indexを通してvariablesとmixinsの内容を一括で利用しています。@forwardによってindexが公開レイヤになります。
@forward の show / hide オプションで API を制御する
特定の変数だけを公開したい場合、show や hide を使えます。
1// _variables.scss
2$internal-thing: 10px !default; // for internal use
3$primary-color: #0a74da !default;
4$secondary-color: #f5f5f5 !default;!defaultを付けることで上書き可能なデフォルト値として公開できます。
1// _index.scss
2@forward 'variables' show $primary-color, $secondary-color;
3@forward 'mixins';@forwardのshowを使うことで、外部に公開する内容を必要なものだけに絞ります。内部で使う変数や機能は外から見えなくなります。
モジュールを設定可能にする(with)
モジュール側で !default を使っておくと、読み込み側で with を使って値を上書きできます。
1// _theme.scss
2$brand-color: #ff6600 !default;
3$radius: 4px !default;
4
5@mixin button-style() {
6 background-color: $brand-color;
7 border-radius: $radius;
8}- デフォルト値を
!defaultで定義したモジュールは、withを使って設定を渡せます。
1// main.scss
2@use 'theme' with (
3 $brand-color: #2288ff,
4 $radius: 8px
5);
6
7.my-btn {
8 @include theme.button-style();
9}@useのwithによって読み込み時にモジュール内のデフォルト変数を上書きできます。テーマの差し替えに便利です。- 注意点として、
withは@useを読み込む時だけ効果があり、読み込み後に値を変更することはできません。
実践:ボタンコンポーネント(完全例)
実際にボタンのスタイルをモジュールで設計してみます。まずは変数・ミックスインをモジュールに分けます。
1// _variables.scss
2$btn-padding-y: 8px !default;
3$btn-padding-x: 16px !default;
4$btn-font-size: 14px !default;
5$btn-primary-bg: #0a74da !default;
6$btn-primary-color: #fff !default;- ボタンのデフォルト変数を定義しています。
!defaultにしておくことで読み込み側で上書きできます。
1// _mixins.scss
2@use "variables" as v;
3
4@mixin btn-base() {
5 display: inline-flex;
6 align-items: center;
7 justify-content: center;
8 padding: v.$btn-padding-y v.$btn-padding-x;
9 font-size: v.$btn-font-size;
10 border: none;
11 cursor: pointer;
12}- ボタンのベースミックスインを定義しています。再利用しやすく分離しています。
1// _button.scss
2@use 'variables' as v;
3@use 'mixins' as m;
4
5.button {
6 @include m.btn-base();
7 background: v.$btn-primary-bg;
8 color: v.$btn-primary-color;
9 border-radius: 4px;
10 transition: opacity 0.15s ease;
11 &:hover { opacity: 0.9; }
12}
13
14.button--large {
15 padding: calc(v.$btn-padding-y * 1.5) calc(v.$btn-padding-x * 1.5);
16 font-size: v.$btn-font-size * 1.25;
17}@useによる名前空間参照でボタンスタイルを作成しています。バリアントを.button--largeとして定義しました。
1// main.scss
2@use 'button'; // or @use 'index' that forwards button, variables, mixinsbuttonモジュールを読み込むだけで、button のスタイルが使えるようになります。
テーマ切替(複数のテーマファイルを用意する)
テーマ差し替えは with による設定か、または別モジュールを作って @use を切り替える方法が使えます。
1// themes/_light.scss
2$brand-color: #0a74da !default;1// themes/_dark.scss
2$brand-color: #111827 !default;- 複数のテーマファイルでブランド色などを定義しておき、ビルドもしくは読み込みで切り替えます。
1// main.scss (light theme)
2@use 'theme' with ($brand-color: #0a74da);
3@use 'button';withを使うか、ビルド時に@use 'themes/light'を読み込むことでテーマを決めます。
プライベートとパブリック(プレフィックス _ と !default)
SASS では、ファイル名の先頭にアンダースコアを付けると部分ファイルとして扱われます。しかし、モジュールの公開・非公開を管理する際は、@forwardのshowやhide を使ってエクスポート範囲を制御します。
公開する API は @forward で整理し、内部実装が外部から見えないようにすることができます。
実務で役立つベストプラクティス
以下は、SASS を実務で使うときに役立つ基本的な考え方をまとめたものです。どれも開発を進める上で迷いを減らし、コードを整理しやすくするための指針になります。
- 変数はテーマとして変更する可能性がある場合は
!defaultを付けておきます。これにより利用する側が値を上書きしやすくなります。 - モジュールは役割ごとに小さく分け、ひとつの責務に集中させます。変数、ミックスイン、コンポーネントのように分けると整理しやすくなります。
- 公開する内容は
@forwardで管理し、必要に応じてshowとhideを使い分けます。公開範囲を明確にすることで安全な設計になります。 - ネームスペースを活用して、どのモジュールの機能なのかを分かりやすくします。他のコードとの混同を防ぐことができます。
withは@useで読み込むときだけ効果がある点を押さえておきます。後から変更できないため、設定は読み込み時に行うようにします。- ファイル名は先頭にアンダースコアを付けて部分ファイルにし、単体ではコンパイルされないようにします。大きな構成にまとめやすくなります。
- テストやドキュメントの理解を助けるために、
indexモジュールに使用例を載せておくと便利です。利用者が挙動をつかみやすくなります。
これらのポイントを意識すると、プロジェクトが大きくなったときでも管理しやすくなり、チーム全体で読みやすいコードを維持できます。
まとめ
SASSのモジュールシステムは、名前空間や公開APIや設定のしやすさを通してスタイルコードを整理します。@use と @forward をうまく使い分けることで、チームでの開発やテーマの切り替えやライブラリの設計がぐっと楽になります。
YouTubeチャンネルでは、Visual Studio Codeを用いて上記の記事を見ながら確認できます。 ぜひYouTubeチャンネルもご覧ください。