[css][sass]mapを使って共通要素の設定を一括管理
最近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便利。