Sass/Scssでデフォルト引数を指定する際の引数順序依存を改善する
SCSSは非常に便利で開発の効率も上がりますが、かゆいところに手が届かないといったことも結構あります。今回はその1つである、引数の順序依存を改善する方法を紹介します。
デフォルト引数とは
たとえば、こんな関数を作ってみます。全体の幅とガター幅が分かっていて、均等分割したいとき、1カラムの横幅はいくつになるか求める関数です。
@function getColumnWidth($container : 1200, $column: 5, $gutter : 10)
{
@return ($container - ($column - 1) * $gutter) / $column;
}
こんな感じで記述すれば、1カラムの幅が算出できます。引数の $container は全体の幅、$column は分割数、$gutter はガター幅ですね。引数を見てみると、初期値が設定されていると思います。$container は1200、$column は5、$gutter は10となっています。
@debug getColumnWidth();
@debug getColumnWidth(500);
@debug getColumnWidth(700, 10);
@debug getColumnWidth(300, 4, 20);
デフォルト引数されているので、引数を省略して呼び出すことができますね。しかし、$container の値は初期値のままで、$column の値だけ変えたい場合もあると思います。
// 誤り
@debug getColumnWidth( , 10);
// 正しい
@debug getColumnWidth(1200, 10);
しかし、省略できるのは第2引数または第2第3引数が記述されていないときです。つまり、$column の値だけ変えたくても、$container の値を入力しなければならないのです。これでは、融通がききにくいですよね。
map
そんなときに便利なのがmapという機能です。
@function getColumnWidth($arguments : ())
{
$default : (container : 1200, column : 5, gutter : 10);
$merge : map-merge($default, $arguments);
$container : map-get($merge, container);
$column : map-get($merge, column);
$gutter : map-get($merge, gutter);
@return ($container - ($column - 1) * $gutter) / $column;
}
// columnの値だけ変えることができる
@debug getColumnWidth((column : 2));
// gutterも変えたければ
@debug getColumnWidth((column : 2, gutter: 20));
初期値を関数内に記述して、map-merge() します。これで、デフォルト引数を上書きさせることができます。ただし、呼び出すとき、引数はmap型でなくてはならないので二重括弧となります。
可変長引数
二重括弧が気になる方は可変長引数を使ってみるといいと思います。
@function getColumnWidth($arguments...)
{
$default : (container : 1200, column : 5, gutter : 10);
$arguments : keywords($arguments);
$merge : map-merge($default, $arguments);
$container : map-get($merge, container);
$column : map-get($merge, column);
$gutter : map-get($merge, gutter);
@return ($container - ($column - 1) * $gutter) / $column;
}
// columnの値だけ変えることができる
// 二重括弧なし
@debug getColumnWidth($column : 5);
// gutterも変えたければ
@debug getColumnWidth($column : 5, $gutter : 24);
先ほどと違うところは、keywords() 関数を使用しているところですね。この関数は可変長引数をmap型に変換してくれる関数です。結局mapを使うので先ほどと原理は変わりません。