APG Patterns
English
English
📊

グリッドとテーブルのプロパティ

グリッドやテーブルの構造と関係性を完全に伝えるために、制作者は ARIA の行と列のプロパティが正しく設定されていることを確認する必要があります。

このプラクティスの詳細は Grid and Table Properties - WAI-ARIA APG を参照してください。 以下は、このサイトの実装例に基づく補足解説です。

概要

グリッドとテーブルは構造化されたデータを表示するために使用されます。スクリーンリーダーユーザーがこのデータをナビゲートし理解するためには、適切なARIAプロパティで構造(行数・列数、ヘッダー、セルの関係)を伝える必要があります。このプラクティスでは、これらのプロパティを正しく設定する方法を説明します。

テーブル vs グリッドの使い分け

パターン使用場面キーボード動作
table静的、読み取り専用のデータ標準のタブナビゲーション
gridインタラクティブなセル(編集可能、操作可能)セル間を矢印キーでナビゲーション
treegrid展開可能な行を持つ階層データ矢印キー + 展開/折りたたみ

必須のARIAプロパティ

行数と列数

仮想スクロールや部分的なデータ表示を使用する場合:

<div role="grid" aria-rowcount="1000" aria-colcount="5">
<div role="row" aria-rowindex="10">
  <div role="gridcell" aria-colindex="1">...</div>
</div>
</div>
DOM には 10〜20 行目のみレンダリングされています。aria-rowcount と aria-rowindex がデータセット全体のサイズと位置をスクリーンリーダーに伝えます。
プロパティ目的
aria-rowcount行の総数(非表示を含む)
aria-colcount列の総数(非表示を含む)
aria-rowindex現在の行の位置(1始まり)
aria-colindex現在のセルの列位置(1始まり)

セルの結合

複数の行または列にまたがるセル:

<div role="gridcell" aria-colspan="2">2列にまたがる</div>
<div role="gridcell" aria-rowspan="3">3行にまたがる</div>

ヘッダー

columnheaderrowheader ロールを使用:

<div role="grid">
  <div role="row">
    <div role="columnheader">名前</div>
    <div role="columnheader">メール</div>
  </div>
  <div role="row">
    <div role="rowheader">山田太郎</div>
    <div role="gridcell">taro@example.com</div>
  </div>
</div>

ネイティブHTMLテーブルの拡張

ネイティブの <table> 要素を使用する場合、ほとんどのプロパティは暗黙的です:

<table>
<thead>
  <tr>
    <th scope="col">商品</th>
    <th scope="col">価格</th>
  </tr>
</thead>
<tbody>
  <tr>
    <th scope="row">ウィジェット</th>
    <td>¥1,000</td>
  </tr>
</tbody>
</table>
scope="col" の th は暗黙的に columnheader ロール、scope="row" の th は rowheader ロール、td は cell ロールを持ちます。

ARIAは必要な場合(仮想スクロール、動的更新)にのみ追加:

<table aria-rowcount="500">
  <tbody>
    <tr aria-rowindex="50">
      ...
    </tr>
  </tbody>
</table>

実装のポイント

ソート状態

ソート可能な列と現在のソート状態を示す:

<div role="columnheader" aria-sort="ascending">名前 ↑</div>
<div role="columnheader" aria-sort="none">メール</div>
意味
ascending昇順(A-Z、小→大)
descending降順(Z-A、大→小)
noneソート可能だが現在はソートされていない
other他のアルゴリズムでソート

読み取り専用と無効状態

<div role="gridcell" aria-readonly="true">固定値</div>
読み取り専用セル — 値を編集できません。
<div role="gridcell" aria-disabled="true">利用不可</div>
無効なセル — インタラクションが利用できません。

選択状態

選択可能な行やセルを持つグリッド:

<div role="grid" aria-multiselectable="true">
  <div role="row" aria-selected="true">選択中の行</div>
  <div role="row" aria-selected="false">選択されていない行</div>
</div>

よくある間違い

行/列インデックスの欠落

仮想スクロールを使用する場合、スクリーンリーダーがセルの位置を認識できるよう、常にインデックスを提供する:

<div role="row">...</div>
悪い例: 位置情報がないため、スクリーンリーダーがデータセット内の行位置を判断できません。
<div role="row" aria-rowindex="50">...</div>
良い例: 明確な位置 — スクリーンリーダーが「50行目」と読み上げられます。

ネイティブテーブルでの不正なscope

<th>名前</th>
悪い例: scope がないため、スクリーンリーダーがヘッダーと列・行の関連付けを正しく行えない可能性があります。
<th scope="col">名前</th>
<th scope="row">太郎</th>
良い例: 明示的な scope でヘッダーの方向(列または行)を明確にします。

非インタラクティブなテーブルにgridを使用

個々のセルとのインタラクションが不要な場合は、grid ロールではなく table ロールを使用して、キーボードナビゲーションの不要な複雑さを避ける。

リソース