脱・DIV地獄:table要素を「正しく」使いこなすためのセマンティック・アーキテクチャ
現場でコードレビューをしていると、未だに「テーブルレイアウト」の亡霊に怯えて、全てを `div` や `flex` で組もうとするエンジニアに出会うことがあります。あるいは逆に、古いマインドセットのまま、中身を考えずに `table` を詰め込んでしまうケースも少なくありません。
しかし、HTML5以降の `table` は、単なる「見た目の枠組み」ではありません。「データに命を吹き込むための骨格」です。今日は、中級者の皆さんが改めて立ち返るべき、`table` 要素の正しい構成と、ブラウザが裏でどう解釈しているのかという「深層」に焦点を当てて解説します。
—
1. tableは「データの関係性」を定義する場所である
まず大前提として、`table` は「行(row)」と「列(column)」の交差点に意味があるデータのためのものです。単に要素を横並びにしたいだけなら、それは `grid` や `flexbox` の仕事です。
HTML5における `table` の役割は、アクセシビリティの文脈で極めて重要です。スクリーンリーダーは、`thead` や `th` のスコープ(scope)属性を見て、そのデータが「何の項目に対する値なのか」をユーザーに伝えます。この構造を無視することは、視覚障がいを持つユーザーからデータのコンテキストを奪うことに他なりません。
2. ブラウザが裏側で行っている「暗黙の補完」という罠
あまり知られていませんが、ブラウザのHTMLパーサーは非常に優秀です。例えば、あなたが `
| データ |
` と書いたとき、ブラウザは裏側で勝手に `
` を挿入して構造を補完しています。これは便利に見えますが、「意図しない構造」でレンダリングされるリスクを孕んでいます。特にJavaScriptで `document.querySelector(‘table’).children` を叩いたとき、期待した `tr` が取れず、`tbody` が挟まっていることに気づいて混乱する……というのは、新人時代に誰もが通る道です。
したがって、「ブラウザの空気を読む機能」に頼らず、自分たちで明示的にセクションを定義するのがプロの作法です。
—
3. 実践:堅牢で美しいテーブルの構造
以下は、実務でそのまま使える、セマンティックで拡張性の高いテーブルのテンプレートです。
| 商品名 | 価格 | 在庫状況 |
|---|---|---|
| プレミアム・プラン | ¥10,000 | 在庫あり |
| ベーシック・プラン | ¥3,000 | 完売 |
| 合計 | ¥13,000 | |
このコードの「こだわり」ポイント
1. `
`td` ごとに `class` を振る「コピペ地獄」から解放されます。特定の列の背景色や幅を制御したい場合、ここで定義しておけばCSS側で一元管理が可能です。
2. `scope` 属性:
`th` に `scope=”col”`(列ヘッダー)や `scope=”row”`(行ヘッダー)を付けることで、支援技術に対して「このデータはどの項目に属するか」を明確に伝えています。
3. `tfoot` の採用:
合計値や統計値を表示する場合、`tbody` の中に混ぜてはいけません。`tfoot` を使うことで、文書構造として「末尾の要約である」という意図が明確になります。
—
4. シニアからのアドバイス:テーブルは「責務」を全うさせる
最後に、実務における重要なTipsを一つ。
「テーブルの中に複雑なインタラクションを詰め込まない」
例えば、`td` の中に大量のフォーム要素や、複雑なモーダル開閉ボタンを入れすぎると、メンテナンス性が著しく低下します。テーブルはあくまで「データの閲覧」に特化させ、編集や削除といったアクションは、必要に応じて別のUI(サイドパネルや別画面)に分離する勇気を持ってください。
HTMLの構造を綺麗に保つことは、単なる自己満足ではなく、将来の自分やチームメンバーが「どこに何があるか」を瞬時に理解するためのコードに対する敬意です。
まずは手元のプロジェクトで、`tbody` が省略されているテーブルがないかチェックすることから始めてみませんか? きっと、コードの背後にある「ブラウザとの対話」がもっと面白くなるはずです。

コメント