大量の情報をノイズなく整頓し、ユーザーが「比較」「スキャン」「操作」できる基盤を作るためのコンポーネント。
この記事を読むと、整列ルール・バリアント選択・A11y要件の判断が自分でできるようになります。
1. UI例(Preview / Live)
実装で見る(GunjoUI)
この部品を、デザインシステム GUNJO の実装で確かめられます。
2. 定義(Definition)
行(Row)と列(Column)のグリッド構造によって、同種の構造化されたデータを一覧表示・比較するためのUIパターン。
レイアウトとの違い:ページ全体の配置にはCSS GridやFlexboxを使用し、<table> は純粋な「表形式データ」の提示にのみ使用する。
3. 使い分け(When to use / When NOT to use)
3.1 When to use
- 複数のデータ項目(名前、日付、金額、状態など)を同時に見比べる必要があるとき
- ユーザーが大量のデータを一括で確認、ソート、フィルタリングしたいとき
- 管理画面(Dashboard)におけるユーザーリストや取引履歴などの構造化データ表現
3.2 When NOT to use
- データ項目が少なく、画像や説明文などリッチな表現を優先したい場合(Card / List を使うべき)
- モバイル環境など極端に横幅が狭く、2列以上を並べるのが困難な場合(Stacked Listに切り替えるべき)
- ページ全体のレイアウトを組むためのグリッドとして(CSSを使用すべき)
3.3 代替UI(Alternatives)
- リッチな単体情報の羅列 →
Card/List - スマホでの一覧表示 →
Stacked List/Data List
4. 設計判断の核(Decision Principles)
「行を読む」のではなく「列をスキャン」しやすくする。
判断の優先順位:① 揃え(桁数・文字種) → ② 線の排除(ノイズレス) → ③ 識別性(行の区別) → ④ スクロール耐性
- 見出し・配置(揃え)・余白をコントロールし、極限まで「線を減らす」ことでデータを主役にする
- 文字の種類によってセルの揃え位置を変え、視覚的な比較を最大限に容易にする
- ヘッダーの揃えはデータの揃えと必ず一致させる(数値列のヘッダーも右揃え)
5. 状態設計(States)
5.1 必須状態(Required)
- Default:ヘッダーとデータ行が整列し、ノイズとなる線が最小限に抑えられている状態
- Hover:マウスオーバーされた行全体の背景色がかすかに変わり、視線のトラッキングを補助する状態
- Empty:データが1件もない場合の「データがありません」という明確なフィードバック状態
5.2 条件付き状態(Conditional)
- Selected:行の先頭Checkbox等で選択され、行全体がハイライトされている状態
- Loading:スケルトンスクリーンやローディングインジケーターが表示されている状態
5.3 State Gallery
| 状態 | 必須 | 何を伝えるか |
|---|---|---|
| Default | ✅ | 最適な余白と揃えでデータを読みやすく提示する |
| Hover | ✅ | どの行を見ているか(視線位置)をサポートする |
| Empty | ✅ | データが存在しないこと(エラーではないこと)を伝える |
| Selected | — | この行に対する一括操作が準備されていることを示す |
| Loading | — | データセットを現在取得中であることを伝える |
6. バリエーション設計(Variants)
見た目の違いではなく、役割とデータ量によってバリアントを選ぶ。
| バリアント | 目的 |
|---|---|
| Basic Table | 標準的なデータ表示。淡い横線のみで区切る |
| Zebra Striped Table | 行数が非常に多く、横に長いデータ。偶数行・奇数行で背景色を交互に変え視線を誘導する |
| Sticky Header Table | 縦にスクロールしても見出しを固定させ、列の意味を失わせない |
禁止パターン:セルを縦横の黒く太い線(Border)で完全に囲む「エクセル風の罫線」は、著しく可読性を下げるため避ける。
7. パターン集(Good / Bad / How to fix)
7.0 よく崩れる設計パターン(3つ)
- 全て中央揃え:文字の開始位置や数値の桁数がばらばらになり、目が疲労する
- 縦線の過剰な使用:データよりもグリッドの「線」が目立ってしまいノイズになる
- モバイル破綻:列が多すぎる表をスマホで無理やり縮小し、文字が潰れる
7.1 Bad(典型3つ)
- タイトル・金額・日付などの「全てが中央揃え(Center)」にされている
- 四方に黒くて太い境界線(Border)が縦横に引かれている
- アクション(編集/削除)ボタンが各行の中央付近などバラバラの列に配置されている
7.2 Good(対になる3つ)
- テキストは左、数値は右に「揃え位置」がデータ型ごとに統一され、ヘッダーもそれに揃っている
- 縦線はなく、淡い横線と十分な余白(Padding)のみでクリーンに分離されている
- アクション用のボタンは最も右側の列に固定されているか、一括操作メニューにまとめられている
7.3 How to fix(手順)
- テーブル内の
text-centerを全て削除する - 列の中身が「テキスト」か「数値」かを見極め、テキストは左揃え、数値は右揃えにする
- ヘッダー(
<th>)の揃えを、その列のデータの揃えと一致させる - 縦のボーダー線(
border-x)を消し、セル内の余白(Padding)を上下左右に十分確保する - 視線誘導のために、行に
hover:bg-mutedやZebra Stripingを適用する
8. ルール(Must / Better)
Must(守らないと壊れる)
Better(品質が跳ねる)
9. アクセシビリティ要件(必須)
Keyboard
- テーブル内でインタラクティブな要素(リンク、ボタン)がある場合、
Tabキーで正しい順序(左から右、上から下)で移動できること - 行選択チェックボックスがある場合、
Spaceキーで選択できること
Focus
- キーボードで移動可能なセルや行、内部のアクションボタンに明確なフォーカスリング(
focus-visible)を表示する
Screen Reader
- データ整理のための
<table>,<thead>,<tbody>,<tr>,<th>,<td>タグを正しく使用する(レイアウト目的の<table>は使わない) - ヘッダー
<th>にはscope="col"やscope="row"属性を付与し、セルが何のデータかスクリーンリーダーが紐づけられるようにする
Touch / Pointer
- モバイルでの横スクロールを考慮し、スクロール可能であることを視覚的(影や矢印等)に示すか、親コンテナに
overflow-x-autoを設定する
Contrast / Readability
- Zebra Stripingやホバー時のハイライトを用いて、広大な表でも視線が迷子にならないよう配慮する
10. 実装メモ(Implementation Notes)
- Tailwind CSSでテーブルを組む際、親の
divにoverflow-x-autoを付けることでスマホ画面でもレイアウト崩れを防げる - Semantic HTMLを維持するため、
<div>グリッドで無理やり表を作らず、標準のHTMLテーブル要素を使う(Screen Readerフレンドリー) - ヘッダーの固定は
sticky top-0と背景色指定(透過しない色)の組み合わせで実装可能 - ソート状態は
aria-sort="ascending"/"descending"/"none"を<th>に付与するとスクリーンリーダーに伝わる
11. 関連リンク
- 関連するUIデザイン原則: 視覚的階層 (Visual Hierarchy), チャンク化 (Chunking), 情報アーキテクチャ (Information Architecture)
- 用語集(定義): アクセシビリティ (Accessibility)
- 関連するUIコンポーネント(横): Pagination(ページネーション), Checkbox(チェックボックス)
まとめ
美しいテーブル設計とは「データを装飾すること」ではなく、「データを覆い隠すノイズを取り払うこと」です。迷ったら 4. 設計判断の核 に戻り、文字の揃え方(数字は右・テキストは左)と線の引き算という最も基本的なルールから確認してください。<th scope="col"> を正しく付与することがA11y対応の最低ラインです。