エクセルやスプレッドシートで悪手と言われているセル結合。しかし表の見せ方としてはやはり重要度の高い表現でもあり、HTML/CSS上でもその表現は用いたいときもある。
また、表というは本来データの繰り返しを2軸で表すことで、俯瞰的に情報の確認をしやすくするものであり、その繰り返しこそに真価があると思う。
例えば下記のような表を作りたいとする。
3人のなにかの点数が表として並べれている。点数が記録されているものは「国語」と「算数」の2つで、この2つが3人分繰り返されているのだ。
昔ながらの手法(テーブルレイアウト)
これをたとえば昔なつかしのテーブルでレイアウトすると下記のようになる。
余談だが、 これは表として用いているので、Tableタグを使うこと自体は何も間違いではない。
// slim tempalte
table
tr
th(rowspan="2")
|Aさん
td 国語
td 80点
tr
td 算数
td 72点
tr
th(rowspan="2")
|Bさん
td 国語
td 42点
tr
td 算数
td 60点
tr
th(rowspan="2")
|Cさん
td 国語
td 9999点
tr
td 算数
td 0点
あとはこれをCSSでデコレーションしてあげれば完成である。
完成ではあるのだが、これはちょっとした問題が含まれている。
それはレイアウトの変更に弱いという点。昨今のマルチデバイス対応を考えると、具体的には大きな表をスマホで表示させたい際には勝手が悪いのだ。
できることなら、ulやdlタグを用いてCSSでレイアウトしたい。そこで用いられるのが display: grid;
である
gridレイアウトでの表現方法
display: grid;
は、スプレッドシートのような整列したセル内に配置するように、子要素を配置できるとても画期的なレイアウトシステムである。
これにより、昔Tableタグで行われていたレイアウトシステムを、HTML側でのドキュメントの構造を崩すことなく利用できるようになった。
ただ、 display: grid;
は、行単位もしくは列単位での繰り返しに用いるためのプロパティは用意されているのだが、繰り返しパターンを設定してそれを繰り返すみたいな、上記の「国語と算数の点数を持つ表を人毎に繰り返したい」とするためのプロパティは用意されていない。下記のHTMLをそのまま rowspanを含む 2x3 のテーブルの繰り返しにする方法がないのである。やはりレイアウトのためのCSSであって、表組みには用いるのは無理なのか…
と、思ったのだが、ちょっとしたパズルを解く感覚でdisplay: grid;
の設定を調整すると、無事実現できることがわかった。
それが下記である。
dl.grid
.group
dt.name Aさん
dd.subject 国語
dd.point 80点
dd.subject 算数
dd.point 72点
.group
dt.name Bさん
dd.subject 国語
dd.point 42点
dd.subject 算数
dd.point 60点
.group
dt.name Cさん
dd.subject 国語
dd.point 9999点
dd.subject 算数
dd.point 0点
.grid
display: grid
grid-tempate-columns: 1fr 1fr 1fr
grid-tempalte-rows: 1fr 1fr
.group
// ↓ 読みやすさのために包んでいるだけなので、 gridレイアウトの対象からはずす
display: contents
.name
grid-column: 1
grid-row: auto / span 2
// ↑ grid-row のスタートを auto にして自動流し込み位置に依存させることで、
border: 1px solid #333
.subject
border: 1px solid #333
margin: 0
.point
border: 1px solid #333
margin: 0
大事なのは、 .name
の grid-row
を auto / span 2
にすることだけである。
span 2
は、「縦に2マス、セル結合してください」という意味になるのだが、MDNなどを確認しても「指定された開始番号の位置から、2マス結合します」みたいな使用例しかなく、流し込み位置から縦2マス結合する方法がわからなかったのだが、普通にauto
でそれが実現できた。
上記コードを実装し、ブラウザで表示したものが下記になる。
あとはテーブルのときと同様に、CSSを追加してデコレーションしてあげれば良い。