Sassではいわゆる「配列」のような複数のデータを格納するリストを作れる……というのだけど使ったことなかった。リファレンスでもさらっと流されてるし、リストを使う@eachの説明でもベタに並べてあるだけで、どうやって作ってどうやって使うのかイメージできなかった。変数の値を空白区切りにしたらリストな変数になるということはどう考えてもリファレンスからは読み取れないと思う。

基本

特に難しいこともなく空白(かカンマ)区切りで指定するとリストになる。

$lists: foo bar buz;

.test {
  property: $lists;
}

リストな変数であってもそのまま参照した場合は普通の変数と同じようにそのまま(空白区切りのまま)出力される。

.test {
  property: foo bar buz }

リストの特定のインデックスの値を参照するにはnth()関数を使う。

.test {
  property: nth($lists, 2);
}

これでリストの2番目の値を参照できる。多くのプログラミング言語と違って添え字は1始まりなことには注意が必要。

.test {
  property: bar }

書きづらいこと以外はまぁ普通な感じ。

応用

変数をそのままリストの値にすることもできる。

$foo: f o o;
$bar: b a r;
$buz: b u z;
$lists: $foo $bar $buz;

.test {
  property: nth($lists, 3);
}

勿論(?)このようにリストをリストにぶち込むとかも出来て、こうすると多次元配列っぽいものになる。この場合は基本の最初の例のように空白区切りでの出力となる。

.test {
  property: b u z }

nth()関数をネストすればどんどん辿れる。

.test {
  property: nth(nth($lists, 3), 2);

これでリストに格納したリストの特定のインデックスを参照できる。

.test {
  property: u }

素晴らしい。

具体的な利用

幅とそれを利用したクラスが必要なカラム定義なんかに利用できる。

$column: 60px;
$gutter: 20px;
$gap:    10px;

$colspan1:  (($column + $gutter) *  1 - $gutter);
$colspan2:  (($column + $gutter) *  2 - $gutter);
...
$colspan11: (($column + $gutter) * 11 - $gutter);
$colspan12: (($column + $gutter) * 12 - $gutter);
$colspan: $colspan1 $colspan2 ... $colspan11 $colspan12;

@for $i from 1 through 12 {
  .colspan#{$i} {
    margin-left: $gap;
    margin-right: $gap;
    float: left;
    width: nth($colspan, $i);
  }
}

このように変数を使って変数を参照することができる。append()関数も使えばもっとうまく短く書けそう。


なんてことをカラム定義を生成するSCSSパーシャルを作ってて理解した。でもけっこうな魔窟っぽい予感がするので気をつけて使った方が良さそう。

追記

append()を使うと短くはなる。空のリスト(というか変数?)も作ることができるようなので以下のような感じで書ける。

$column: 60px;
$gutter: 20px;
$gap:    10px;

$colspan: ();

@for $i from 1 through 16 {
  $colspan: append($colspan, (($column + $gutter) * $i - $gutter));
}

スッキリ!

3.2のprerelease版では複数のリストを明示的に多次元リストにまとめるzip()とリストから検索するindex()という関数も追加されている。駆使すると今はできない同じルールセット内の別プロパティーの値とかを参照するみたいな機能作れそう。多分誰も読めなくなるけど。