【CSS】display: containerを使ってdisplay: gridで作った表を直感的なDOM構造にする

  • 2025年4月3日
  • CSS

 display: gridは便利であり様々な使い方ができます。これを表のように使いたくなるときがあります。例えば次のようなコードで表のようなレイアウトを実現できます。

<div class="table">
  <div>名前</div>
  <div>年齢</div>
  <div>職業</div>

  <div>田中</div>
  <div>30</div>
  <div>エンジニア</div>

  <div>佐藤</div>
  <div>25</div>
  <div>デザイナー</div>
</div>

.table {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 4px;
  border: 1px solid #ccc;
  padding: 8px;
}
.table > div {
  padding: 4px;
  background-color: #f9f9f9;
}

 こんな感じで表を作れます。ただ、これはDOM的にはいまいちわかりにくいものになっています。行が変わってもただ div が連続しているだけです。こうなっていると行単位や列単位で操作するクエリを書くのが手間になります(一応 nth-child を駆使すればできなくはないです)。そこで行を表す要素で行内のセル要素を括りたくなります。しかしながら単に要素を増やすだけだとグリッドデザインを壊すことになってしまいます。表としての見た目を崩さずにこれを実現しようとする場合 display: contentsが使えます。

 display: contentsな要素はDOM要素ではあるけど、レイアウト上ではその存在が無視されます。具体的にはdisplay: contentsな要素はdisplay: gridの直下でもグリッドアイテムとしては扱われません。代わりにdisplay: contents直下の要素らがグリッドアイテムとして扱われます。これを利用することでDOM構造が明確で扱いやすいdisplay: gridで作った表を実現できます。

display – CSS: カスケーディングスタイルシート | MDN#contents

 実際にdisplay: contentsを使ったグリッドデザインの表が次です。

See the Pen
display contents
by cpt-sugiura (@cpt-sugiura)
on CodePen.

<div class="table">
  <div class="row">
    <div>名前</div>
    <div>年齢</div>
    <div>職業</div>
  </div>
  <div class="row">
    <div>田中</div>
    <div>30</div>
    <div>エンジニア</div>
  </div>
  <div class="row">
    <div>佐藤</div>
    <div>25</div>
    <div>デザイナー</div>
  </div>
</div>

.table {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 4px;
  border: 1px solid #ccc;
  padding: 8px;
}
.row {
  display: contents; /* この要素自体はレイアウトに現れない */
}
 
.table > .row > div {
  padding: 4px;
  background-color: #f9f9f9;
  transition: background-color 0.2s;
}
.table > .row.header > div  {
  background-color: #ddf;
}
 
/* ホバー時:行ごとに背景色を変える */
.table > .row:hover > div {
  background-color: #e0f7ff;
}

 DOM構造が見た目と一致するようになり行単位でスタイルをあてるのが容易になりました。こうすると例にある行にホバーした際の背景色変更といったスタイルも容易に記述できます。

 こんな感じでdisplay: contentsは作りたいデザインとあるべきDOM構造の差異を吸収することができます。CSSに限らずクエリセレクタが複雑、コンポーネントの都合で複数要素をそのまま渡せない、扱いにくいくらい多重にネストされた要素になってしまう、などといった事態が起きた時、display: contentsな要素を作ることでそれを解決しやすいです。

>株式会社シーポイントラボ

株式会社シーポイントラボ

TEL:053-543-9889
営業時間:9:00~18:00(月〜金)
住所:〒432-8003
   静岡県浜松市中央区和地山3-1-7
   浜松イノベーションキューブ 315
※ご来社の際はインターホンで「316」をお呼びください

CTR IMG