!default。

Sassを書く時には変数を多用することと思います。それら変数は自分で定義して自分で使うので、同じプロジェクト内で再定義する必要はあまりありません。しかし他人や自分の作ったSassファイルを流用する場合、その中で使われている変数の値を最適化する必要が出てきます。もしその変数がハード・コーディングされているだけだとしたらどうでしょうか? その場合変数を直接書き換えることになるでしょう。こういったSassファイルの再利用における問題を解決するためにSassには!defaultというフラグが用意されています。

Less & Sass Advent Calendar 2011もついに18日目ですね。ゴールまであと少しです。


まずはSassリファレンスの!defaultを扱っている部分を読んでみましょう。参考にざっと以下に訳してみました。

変数の値を指定する時、!defaultというフラグを付けておくことにより、変数にまだ値が割り当てられていない時のみ値を割り当てるようにすることができます。どういうことかというと、もし変数に既に値が割り当てられていた場合は再割当てされることはありませんが、まだ値が割り当てられていない場合は指定された値がセットされるということです。

例えば以下のように書くと:

$content: "First content";
$content: "Second content?" !default;
$new_content: "First time reference" !default;

#main {
  content: $content;
  new-content: $new_content;
}

以下のようにコンパイルされます:

#main {
  content: "First content";
  new-content: "First time reference"; }

その具体的な利用

リファレンスの例はその機能の説明にはなっていますが、何のために使うのかイメージしにくいのではないかと思います。!defaultフラグが威力を発揮するのはSassのpartial(わかりづらいので以下ライブラリとします)を書き、それを複数のプロジェクトで使い回すといったケースです。つまり他人に使われることを意識したSassファイルを書く時、ということですね。

!defaultを利用しないライブラリ

ライブラリで!defaultフラグを使わなかった場合にどうなるのでしょうか? 例えば以下のようなデフォルトのフォント設定を定義するライブラリを_font.scssというファイル名で作成したとします。

$font-family: "Helvetica Neue", "Helvetica", "Arial", sans-serif;

body {
  font: 16px/1.5 $font-family;
}

この小さなライブラリを利用した上でフォント・ファミリだけを変えたいという場合、以下のようにすることが多いでしょう。

@import "font";

body {
  font-family: "Lucida Grande", "Lucida Sans Unicode", sans-serif;
}

SCSSファイルとしては特に悪いと言えるところはありません(良いとも言えませんが)。しかしコンパイルすると以下のようなCSSになってしまいます。

body {
  font: 16px/1.5 "Helvetica Neue", "Helvetica", "Arial", sans-serif; }

body {
  font-family: "Lucida Grande", "Lucida Sans Unicode", sans-serif; }

CSSとしては無駄が多く美しくないですよね?

!defaultを使った柔軟なライブラリ

それでは_font.scss!defaultフラグを使って再利用しやすいように書き直してみましょう。

$font-size: 16px !default;
$line-height: 1.5 !default;
$font-family: "Helvetica Neue", "Helvetica", "Arial", sans-serif !default;

body {
  font: $font-size/#{$line-height} $font-family;
}

このようにライブラリ側で適切に!defaultが使われていれば、先程の例と同じようにフォント・ファミリを変更するとすると、利用先では以下のように書くことができます。

$font-family: "Lucida Grande", "Lucida Sans Unicode", sans-serif;

@import "font";

$font-family@importの前で設定してやることに注意してください。こうすることによってライブラリが変数が設定済みであることを認識し、ライブラリ側での変数設定が行われないようになります。

body {
  font: 16px/1.5 "Lucida Grande", "Lucida Sans Unicode", sans-serif; }

コンパイルするとこのような綺麗なCSSが出力されるようになるでしょう。$font-size$line-heightも同様にして設定することが可能です。勿論何も設定しなければ_font.scssで指定されている値が利用されます。


このようにライブラリ内で利用する変数を!defaultフラグを使って定義しておくことによって、

という2つの効果を得ることができます。

SassをはじめとしたCSSメタ言語の魅力のひとつとして、原始的なコピー・アンド・ペーストではなくライブラリやオブジェクトとして柔軟に再利用できるものを記述できるようになることが挙げられると思います。Sassにおいては記述時におけるその機能性からミックスイン@extendがその柱として取り上げられることが多いですが、!defaultフラグもまたそれを支える重要な柱のひとつです。

既存のCSSをSassで書き直すというような作業によりSassに慣れている途中の人達はまだ使うことはあまりないだろうと思いますが、みんなでSassを使い倒すためには必ず必要になってくる知識です。是非マスターして!defaultをうまく使ったライブラリを作ってみてください。