CSS Grid Layout で日本地図

数年ぶりにHTMLまわりを調べていたらCSS Grid Layoutのことを知り、面白そうだったので試してみたの巻です。

CSS Grid Layout

以下の記事を大いに参考にさせていただきました。

これを使えば太古のtableレイアウト的な考え方で今風のレイアウトができますね!

tableレイアウトといえば、昔tableタグでこんなものを作りました。

Grid Layoutならtableタグを使わなくても、要素の並びを地図状に配置できそうです。

というわけで

See the Pen Grid Japan Map by 4b3 (@4b3) on CodePen.

作りました。 よく使いそうなリストとチェックボックスの2パターンを用意しました。

リストではホバー時とアクティブ時に、チェックボックスではそれらに加えて選択状態でスタイルが変わります。

HTML

リスト
<ul class="gridmap">
  <li class="pref hokkaido"><a href="#">北海道</a></li>
  <li class="pref tohoku"><a href="#">青森</a></li>
  〜 中略 〜
  <li class="pref kyushu"><a href="#">沖縄</a></li>
</ul>
チェックボックス
<div class="gridmap">
  <input type="checkbox" name="pref" id="cb01">
  <label for="cb01" class="pref hokkaido">北海道</label>
  <input type="checkbox" name="pref" id="cb02">
  <label for="cb02" class="pref tohoku">青森</label>
  〜 中略 〜
  <input type="checkbox" name="pref" id="cb47">
  <label for="cb47" class="pref kyushu">沖縄</label>
</div>

input:checked + labelで指定できるようにするために、inputlabelを横並びにしています。1 label.prefがグリッドアイテムになります。inputは非表示にします。

また、.prefは色分けのために地方別でクラス分けしています。 グリッドコンテナ直下でないとグリッドアイテムにならないので、例えば.gridmap > .kyushu > .prefのようにまとめることはできなさそうです。

CSS

2パターンともスタイルは共通です。グリッドに関係する部分は以下。

/* グリッドコンテナ */
.gridmap {
  display: grid;
  grid-template:
    "... p01 p01 p01 p01 p01 p01 p01 ... ... ... ... p02 p02 p02 p02" 1fr
    "... p01 p01 p01 p01 p01 p01 p01 ... ... ... ... p05 p05 p03 p03" 1fr
    "... p01 p01 p01 p01 p01 p01 p01 ... ... ... ... p06 p06 p04 p04" 1fr
    "... ... ... ... ... ... ... ... ... p17 p16 p15 p15 p07 p07 p07" 1fr
    "p41 p40 p40 p35 p32 p32 p31 p28 p26 p18 p21 p20 p10 p09 p09 p08" 1fr
    "p42 p43 p44 p35 p34 p34 p33 p28 p26 p25 p21 p20 p11 p11 p11 p08" 1fr
    "... p43 p45 p38 p38 p37 p37 p27 p29 p24 p23 p20 p19 p13 p13 p12" 1fr
    "p47 p46 p45 p39 p39 p36 p36 p30 p30 p24 p23 p22 p22 p14 p14 p12" 1fr
    /2fr 2fr 2fr 2fr 1fr 1fr 2fr 2fr 2fr 2fr 2fr 2fr 2fr 1fr 1fr 2fr;
  gap: 2px;
  grid-gap: 2px;
}
/* グリッドアイテム */
.pref:nth-of-type(1) { grid-area: p01; }
.pref:nth-of-type(2) { grid-area: p02; }
  〜 中略 〜
.pref:nth-of-type(47) { grid-area: p47; }

以下、各プロパティの詳細は解説記事等にお任せして、気づいたことをメモします。

grid-templateはAAっぽく配置を指定することができるというちょっとギョッとする構文ですが、今回みたいなのを作るにはめっちゃ重宝しますね……。 同じ識別子が成す領域は矩形になっている必要があるので、リアル寄りの北海道は描けません。当然識別子が違う箇所でカブっていても駄目。

単位frはグリッドレイアウト専用らしいので使ってみました。 列の幅は基本2frにしていまが、2箇所1fr 1frに分割してるところがあります。その列だけgapの分横に広くなってしまっていますが、目を瞑ります。

gapgrid-gapは前者が新しいらしいですが、Safari 11.1が未対応だったので両方指定しています。

grid-areaは数値(グリッドライン番号)を取りうるので、識別子の頭文字に数字は使えません。 grid-templateのいじりやすさを考えると、HK, AM, IT,... のような都道府県名を想起しやすい識別子もいいかもしれませんね……! →都道府県名の英字2字略号 - 4b3のブログ

あとはスタイルを揃え、お好みで味付けして完成です。

参考記事

参考になった、あるいは一部ネタが被っていた記事です。


  1. いちいちidforが必要で面倒ですね……CSS4ならlabelの中にinputを入れてlabel:has(> input:checked)的な指定ができるのかなと思うんですが……