はじめに
この記事を書いた時点では、Subgrid
のサポートされているブラウザが限られていましたが、2024年3月現在では主要なブラウザでサポートがされています。
そのため、方法③ Subgridを使うがおすすめの方法です。
"subgrid" | Can I use... Support tables for HTML5, CSS3, etc
これは何
Webを作っている際に、「見た目はテーブルレイアウトを使って組むと楽そう」だけど、「実際にはテーブルではない」要素を作りたいことがちょこちょことあります。
以下のようなUIです。
こうした要素をtable要素を使ってデザインしてしまうと、支援技術を使用しているユーザーが意味を適切に理解できなかったり、テーブルを読み取る操作が複雑なために内容を読み取れないことがあります。
テーブル以外でも、基本的に使用するタグは「実現したい見た目」ではなく、「要素が持つ意味」に応じて適したものを使いましょう。
文字サイズを変えたいからheadingを使ったりボタンをdivで作ったりすると、支援技術などで誤った伝わり方をしたり、適切に操作できないことがあります。
こうした時にtable要素を使わずにマークアップ・スタイリングする方法をまとめてみました。
方法① Flexbox
を使う
手順
- 各行を
div
などで囲い、display: flex;
を指定する - 各列に
width
やflex
の値を指定し、横幅が揃うようにする
メリット
- 1行ごとにマークアップできる(情報構造をマークアップで表現できる)
デメリット
- 要素のサイズに応じて各列の横幅を決めることができない
- 各列の位置を揃えるには、要素の内容をに応じてwidthを指定しておくか、要素の位置を取得して計算する必要がある
個人的な所感
内容に応じて柔軟に列の幅を変える必要がないのであれば、この方法で問題ないと思います。
ただしwidth
で固定幅を指定する際は、要素が変わったときに表示崩れなどを起こさないよう注意が必要です。
マークアップとスタイリング
<section>
<div class="flex-row">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
<div class="flex-item">3</div>
</div>
<div class="flex-row">
<div class="flex-item">4</div>
<div class="flex-item">5</div>
<div class="flex-item">6</div>
</div>
</section>
.flex-row {
display: flex;
gap: 4px;
}
.flex-row+.flex-row {
margin-top: 4px;
}
.flex-item {
background: #eee;
padding: 4px;
}
.flex-item:nth-child(1) {
width: 40px;
}
.flex-item:nth-child(2) {
flex: 2;
}
.flex-item:nth-child(3) {
flex: 1;
}
サンプル
See the Pen flex by kabechiyo_shunkaaizawa (@kabechiyo) on CodePen.
方法② grid
を使う
手順
- 要素全体を
div
などで囲い、display: grid;
とgrid-template-columns: repeat([列の数], auto);
を指定する
メリット
- 要素のサイズに応じて各列の横幅を決めることができる
デメリット
- 1行ごとにマークアップできない(情報構造をマークアップで表現できない)
個人的な所感
1行ごとに情報の区切りがないのであれば、この方法がシンプルに実装できます。
1行ごとにマークアップできないため、1行ごとに情報の区切りがある場合は方法①を使う方が良いと思います。
マークアップとスタイリング
<div class="grid-container">
<div class="grid-item">1</div>
<div class="grid-item">2</div>
<div class="grid-item">3</div>
<div class="grid-item">4</div>
<div class="grid-item">5</div>
<div class="grid-item">6</div>
</div>
.grid-container {
display: grid;
gap: 4px;
grid-template-columns: repeat(3, auto);
}
.grid-item {
background: #eee;
padding: 4px;
}
サンプル
See the Pen grid by kabechiyo_shunkaaizawa (@kabechiyo) on CodePen.
方法②-2 grid
とdisplay: contents
を使う
手順
- 要素全体を
div
などで囲い、display: grid;
とgrid-template-columns: repeat([列の数], auto);
を指定する - 各行を
div
などで囲い、display: contents;
を指定する
メリット
- 要素のサイズに応じて各列の横幅を決めることができる
デメリット
-
display: contents;
を指定した要素のroleがアクセシビリティツリー上で無視される
個人的な所感
後述のSubgrid
と近い挙動を実現でき、使い勝手が良いです
行をwrapするタグのロールが失われてしまうので、意味を持たせる場合は方法①を使う方が良いと思います。
この仕様自体はバグらしいので、修正を待ちたいです。
マークアップとスタイリング
<div class="grid-container">
<div class="subgrid-container">
<div class="grid-item">1</div>
<div class="grid-item">2</div>
<div class="grid-item">3</div>
</div>
<div class="subgrid-container">
<div class="grid-item">4</div>
<div class="grid-item">5</div>
<div class="grid-item">6</div>
</div>
</div>
.grid-container {
display: grid;
gap: 4px;
grid-template-columns: repeat(3, auto);
}
.subgrid-container {
display: contents;
}
.grid-item {
background: #eee;
padding: 4px;
}
サンプル
See the Pen Untitled by kabechiyo_shunkaaizawa (@kabechiyo) on CodePen.
方法③ Subgrid
を使う
この方法は現在サポートされているブラウザが限られており、実用的ではありません。
2024年3月現在、主要ブラウザでサポートがされており使うことができるようになりました
"subgrid" | Can I use... Support tables for HTML5, CSS3, etc
手順
- 要素全体を
div
などで囲い、display: grid;
とgrid-template-columns: repeat([列の数], auto);
を指定する - 各行に
display: grid;
,grid-template-columns: subgrid;
,grid-column: span [列の数];
を指定する
メリット
- 1行ごとにマークアップできる(情報構造をマークアップで表現できる)
- 要素のサイズに応じて各列の横幅を決めることができる
デメリット
最初に書いた通り、サポートされているブラウザが限られているため実用的でない
個人的な所感
サポートブラウザが限られている以外は、方法①・②よりも使い勝手が良いので、早く使えるようになってほしい..と思ってます
追記:使えるようになりました!
マークアップとスタイリング
<div class="grid-container">
<div class="subgrid-container">
<div class="grid-item">1</div>
<div class="grid-item">2</div>
<div class="grid-item">3</div>
</div>
<div class="subgrid-container">
<div class="grid-item">4</div>
<div class="grid-item">5</div>
<div class="grid-item">6</div>
</div>
</div>
.grid-container {
display: grid;
gap: 4px;
grid-template-columns: repeat(3, auto);
}
.subgrid-container {
grid-column: span 3;
display: grid;
grid-template-columns: subgrid;
}
.grid-item {
background: #eee;
padding: 4px;
}
サンプル(Firefoxでご覧ください)
See the Pen subgrid by kabechiyo_shunkaaizawa (@kabechiyo) on CodePen.