最近cssを勉強中でsassを使っているのですが、ページ内に何度も登場する似た要素(top, leftがそれぞれ異なる)のcssをうまく管理できないかなと思い調べていたところ、sass3.3から追加されたmap形式(ハッシュ)を使うとキレイに書けそうだったので試してみました。
今回、cssは.scssではなく、.sassで書いていたのですが、.sassの場合は改行を使ってmapを書くことができず、以下のように1行で書く必要がありました。
$sample-map: (map1: (id: 1, top: 10px, left: 10px), map2: ....)
管理する要素が多い場合、1行でmapを書くと非常に分かりづらくなってしまうので
少し気持ち悪いですがmapの部分だけ.scssで書くことにしました。
# _sample_map.scss $sample-map: ( map1: ( top: 10px, left: 10px ), map2: ( top: 12px, left: 20px ) );
上記のscssを記述して、main.sass等で
@import sample_map
とすると$sample-map変数を読み込むことができます。
mapにはキーや値を取得するための関数がいくつか用意されていますが、今回は指定したキーの値を取得するmap-getとマップ内の値をカンマ区切りのリストで取得するmap-valuesを用いて、id(mapのキー名の数字)を引数にして該当mapの値を取得する関数を作成してみます。
# _functions.sass @function mapInfo ($id) @return map-values(map-get($sample-map, "map#{$id}"))
これでmapInfo(1)とすると、top、leftの値(10px, 10px)を取得できるようになりました。
mapを使って管理していると、mixinとfor文を使って一括で設定が書けるようになるので便利です。
# _mixin.sass =map-block($top: 0px, $left: 0px) position: absolute width: 100px height: 100px top: $top left: $left # _sample.sass .sample @for $i from 1 through 2 &.map-sample#{$i} +map-block(mapInfo($i)...)
map-blockのmixinには可変長引数(…)を使って引数を渡しています。
これをコンパイルすると以下のようにtopとleftのみが異なるcssが出力されます。
mapを使うことで設定ファイル(_sample_map.scss)で要素の位置情報を一括管理できるようになりました。
.sample.map-sample1 { position: absolute; width: 100px; height: 100px; top: 10px; left: 10px; } .sample.map-sample2 { position: absolute; width: 100px; height: 100px; top: 12px; left: 20px; }
追記
ここまでサンプルを書きながら試していて気づいたのですが、mapは可変長キーワード引数として使えるそうです。
サンプルでは、わざわざmapInfo関数を作成してリストを取得し、リストを可変長引数としてmixinに渡していましたが、可変長キーワード引数を使えば、map-getの内容をそのままmixinに渡すだけでよくなります。
また、キーと値が紐付いているのでmixinに渡す順番が異なってもうまく動きます。
というわけで可変長キーワード引数を使ったほうがお手軽ですね。
# _sample.sass .sample @for $i from 1 through 2 &.map-sample#{$i} +map-block(map-get($sample-map, "map#{$i}")...)
sass便利。
参考
- Sass 3.3で追加された新しいデータタイプ「マップ」まとめ解説 | HTML5Experts.jp
- Multiline declaration of maps in SASS · Issue #1088 · sass/sass
- About multiline lists and maps · Issue #56 · HugoGiraudel/sass-guidelines
- Sass 3.3 (Maptastic Maple)