LoginSignup
0
3

More than 1 year has passed since last update.

CSSの display: grid; で、 rowspanを含む 2x3 のテーブルの繰り返しを作りたい

Last updated at Posted at 2023-02-19

エクセルやスプレッドシートで悪手と言われているセル結合。しかし表の見せ方としてはやはり重要度の高い表現でもあり、HTML/CSS上でもその表現は用いたいときもある。
また、表というは本来データの繰り返しを2軸で表すことで、俯瞰的に情報の確認をしやすくするものであり、その繰り返しこそに真価があると思う。

例えば下記のような表を作りたいとする。
3人のなにかの点数が表として並べれている。点数が記録されているものは「国語」と「算数」の2つで、この2つが3人分繰り返されているのだ。

image.png

昔ながらの手法(テーブルレイアウト)

これをたとえば昔なつかしのテーブルでレイアウトすると下記のようになる。
余談だが、 これは表として用いているので、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

大事なのは、 .namegrid-rowauto / span 2 にすることだけである。
span 2 は、「縦に2マス、セル結合してください」という意味になるのだが、MDNなどを確認しても「指定された開始番号の位置から、2マス結合します」みたいな使用例しかなく、流し込み位置から縦2マス結合する方法がわからなかったのだが、普通にautoでそれが実現できた。
上記コードを実装し、ブラウザで表示したものが下記になる。
あとはテーブルのときと同様に、CSSを追加してデコレーションしてあげれば良い。

image.png

0
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
3