[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便利。

参考