CSSの拡張言語Sassの強力な機能の一つは、ファイルを複数に分割できる「Partials」です。ファイルを機能ごとに分割することで、見通しのよいコードを記述できます。近年注目を浴びている「OOCSS」をSassで実現する上でもよく使われています。
しかし、分割するファイルが多くなればなるほど、大量の@import
を記述したり、ファイル分割の度に@import
を書き換える手間がかかります。本エントリーでは、このような大量のimport
文を短くまとめる方法について紹介します。
Sassのファイルの分割と問題点
例えば、_a.scss
と_b.scss
の2ファイルに分割したスタイル設定を、style.scss
にて読み込む設定をしてみます。
.classA {
background-color: red;
}
.classB {
background-color: blue;
}
@import "a";
@import "b";
style.scss
をコンパイルすることで、_a.scss
と_b.scss
が結合されてCSSが出力されます。
.classA {
background-color: red;
}
.classB {
background-color: blue;
}
ファイルの増加と共に増加する@import
2ファイルくらいの場合は特に問題ありませんが、例えば次のように多階層・多数に分割したSassファイルの読み込みを考えてみましょう。
└── sass
├── foundation
│ ├── _foundation1.scss
│ └── _foundation2.scss
├── layout
│ ├── _layout1.scss
│ └── _layout2.scss
├── object
│ ├── component
│ │ ├── _component1.scss
│ │ └── _component2.scss
│ ├── project
│ │ ├── _project1.scss
│ │ └── _project2.scss
│ └── utility
│ ├── _utility1.scss
│ └── _utility2.scss
└── style.scss
これらのSassファイルを読み込む場合、次のように多くの@import
を記述しなければなりません。
@import "foundation/foundation1";
@import "foundation/foundation2";
@import "layout/layout1";
@import "layout/layout2";
@import "object/component/component1";
@import "object/component/component2";
@import "object/project/project1";
@import "object/project/project2";
@import "object/utility/utility1";
@import "object/utility/utility2";
また、ファイルを追加・削除する度に@import
を追加・削除する必要があります。Node.jsのファイル操作機能のように、@import "hoge/**";
という記述(globパターン)ができれば短く済みそうですが、Sassの現在のバージョン(3.4)ではそのような機能はありません。
globパターンが使えるプラグインを使うことでこの問題は解決します。
glob用のプラグインでSassのimport文を減らす
Gulp用のプラグイン「gulp-sass-glob」やNode.jsの「node-sass-globbing」といったプラグインを使うと、Sassにおいても@import "hoge/ **";
の記述でSassファイルの読み込みが可能になります。今回は、Gulp(※)での設定事例を紹介します。
※ 参考記事「5分で導入! タスクランナーGulpでWeb制作を効率化しよう - ICS MEDIA」
環境のセットアップ
まずは環境設定を行います。Gulpがグローバルにインストールされていない場合は、インストールしておいてください(npm install -g gulp-cli
)。
プロジェクトフォルダにて、npmの初期設定を行います
npm init -y
Gulp、Sass、そしてgulp-sass-globのプラグインをローカルにインストールします。
npm i -D gulp gulp-sass gulp-sass-glob
タスクの設定
globを用いて記述されたimport
文を解釈しつつ、style.scss
ファイルをコンパイルするタスクを定義します。
// プラグインの読み込み
const gulp = require("gulp");
const sass = require("gulp-sass");
const sassGlob = require("gulp-sass-glob");
// Sassコンパイルタスクの定義
gulp.task("default", function() {
return gulp.src("sass/style.scss")
.pipe(sassGlob()) // Sassの@importにおけるglobを有効にする
.pipe(sass())
.pipe(gulp.dest("css"));
});
以上で準備は完了です。Sassファイルをコンパイルしてみましょう。
Sassファイルをコンパイルする
任意のSassファイルを準備します。例として、冒頭で示したファイル構成のSassファイルをstyle.scss
で読み込むことを考えます。下記のURLの[Clone or download]よりダウンロードできますので、サンプルを試したい場合はご利用ください。
└── sass
├── foundation
│ ├── _foundation1.scss
│ └── _foundation2.scss
├── layout
│ ├── _layout1.scss
│ └── _layout2.scss
├── object
│ ├── component
│ │ ├── _component1.scss
│ │ └── _component2.scss
│ ├── project
│ │ ├── _project1.scss
(中略)
└── style.scss
▲ コンパイル対象のSassファイル群
globパターンを使って@import
を定義
style.scss
でglobパターンによる@import
を記述します。全てのSassファイル名を記述する必要はなく、最低限の行数のコードで記述可能です。
@import "foundation/**";
@import "layout/**";
@import "object/**";
Sassのコンパイルタスクを実行します
gulp
出力されたCSSを確認すると、目的のCSSファイルが全て読み込まれていることがわかります。
/* foundation1 */
/* foundation2 */
/* layout1 */
/* layout2 */
/* component1 */
/* component2 */
/* project1 */
/* project2 */
/* utility1 */
/* utility2 */
foundation
フォルダやlayout
フォルダでファイルの追加・削除があった場合も、style.scss
を書き換える必要はありません。
ファイル順を無視すればさらに短く
通常の@import
と同じく、記述順にSassファイルは読み込まれます。前述の例では、foundation
、layout
、object
の順番にCSSを読み込むために3つの@import
を記述しましたが、ファイル順を無視できるファイル構成ならば@import
は1行で済みます。
@import "**";
import
文は半分以下になり、ファイルの追加・削除
globを用いることで10行あった@import
は、3行(構成によっては1行)に減りました。
機能ごとにファイルを分割して見通しのよいSassコードを書いたり、OOCSSに基づくCSS設計を行ったとしても、大量の@import
記述に時間を使う必要はありません。glob機能を使いこなし、効率的なSassのコーディングを行いましょう。