tables について
HTMLデータテーブルを作成・確認する開発者やコンテンツ設計者向けのアクセシビリティガイドです。見出しの関連付けを明確にし、複雑さが理解を妨げる場合は構造の簡素化を勧めます。
主な機能
- 01データテーブルとページレイアウトの区別
- 02scopeによる見出しの関連付け
- 03キャプションや文脈によるテーブル名
- 04グループ見出しと複雑な関連付け
- 05レスポンシブ、並べ替え、絞り込みの指針
活用シーン
- 01HTMLテーブルのセマンティックなマークアップ確認
- 02複雑なテーブルのスクリーンリーダー操作改善
- 03並べ替え・絞り込み・ページ分割テーブルの設計
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ mgifford/ accessibility-skills --skill tablesインストール後、Claude Code で/tablesを入力して読み込まれたか確認します。
同梱ファイルREADME.mdSYNC.md
詳細
テーブルアクセシビリティスキル
標準的な出典:
mgifford/ACCESSIBILITY.mdのexamples/TABLES_ACCESSIBILITY_BEST_PRACTICES.mdこのスキルは、そのファイルを基にしています。判断に迷う場合は、そちらの例を優先してください。
HTML のデータテーブルを作成またはレビューする際は、以下のルールを適用してください。 プロジェクトにデータテーブルが含まれる場合にのみ、このスキルを読み込んでください。
基本方針
行と列の関係に意味が依存する情報にはテーブルを使用してください。ユーザーがテーブルを識別し、セル間を移動し、各値に関連する見出しを読み上げられるように、HTML でその関係をマークアップしてください。マークアップの複雑さは情報の複雑さに合わせてください。見出しの関連付けを次々に複雑にするより、テーブルを簡素化したり分割したりするほうが適切な場合がよくあります。
レイアウトにテーブルを使用してはいけません。 代わりに CSS Grid/Flexbox を使用してください。ユーザーがスプレッドシートのようなキーボード操作を本当に必要としない限り、読み取りを目的としたデータテーブルをアプリケーション形式のグリッド(role="grid")に変えてはいけません。
重大度の尺度(このスキル)
| レベル | 意味 |
|---|---|
| Critical | スクリーンリーダーのユーザーがテーブルデータをまったく解釈できない |
| Serious | 見出しがない、または関連付けが誤っている。複雑なテーブルにナビゲーション支援がない |
| Moderate | 1 ページに複数のテーブルがある場合にテーブル名がない。代替手段がなく、強制配色モードで縞模様が失われる |
| Minor | <thead>/<tbody> がない。廃止された summary 属性を使用している |
まず適切な構造を選ぶ
- リスト — 項目が列同士の関係に依存しない場合
- 定義リスト — 用語と説明の組み合わせ
- データテーブル — 行と列のデータを読み取り、比較する場合
- ARIA グリッド/ツリーグリッド — セル間の移動や編集を伴う、アプリケーション形式の複合ウィジェットに限る
- CSS Grid/Flexbox — ページレイアウト
フォームフィールド、カード、画像、またはページ領域を整列させるだけのためにテーブルを使用してはいけません。
重大:すべてのデータテーブルに scope を指定した <th> を含める
<td> セルだけで構成されたテーブルは Critical です。スクリーンリーダーは文脈のない生のデータを読み上げます。行、列、またはグループにラベルを付けるセルには <th> を使用してください。見た目を整えるために太字にした <td> で代用してはいけません。
<table>
<caption>Monthly sales by region, first quarter 2025</caption>
<thead>
<tr>
<th scope="col">Region</th>
<th scope="col">January</th>
<th scope="col">February</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">North</th>
<td>$12,400</td>
<td>$14,200</td>
</tr>
</tbody>
</table>
見出し行または見出し列が 1 つだけの小さく明確なテーブルでは、ブラウザーが <th> のみから見出しの方向を推測できる場合があります。大規模なデータや見た目が似たデータでは、特に scope="col"/scope="row" を明示する方法が、引き続き信頼できる作成上の慣例です。<thead>/<tbody>/<tfoot> は、固定見出し、スタイル設定、スクリプト処理、印刷時の見出しの繰り返しを支援しますが、それらを追加しただけでは、欠落または誤った見出しの関連付けは修正されません。
左上隅のセルが空で、見出しとしての役割がない場合は、<td> のままにしてください。セルを埋めるだけの目的で、「空白」のようなテキストを追加してはいけません。
中程度:キャプションとテーブル名
<caption> は、特に 1 ページに複数のテーブルがある場合に、テーブルを識別するための標準的な方法です。WCAG は、すべての場合にキャプションを必須としているわけではありません。関連する見出しや周囲のテキストで、単純なテーブルを適切に識別できる場合もあります。<caption> を優先的なデフォルトとして扱いつつ、テスト済みの別の関連付けですでに名前が示されている場合は、重複した名前を無理に追加しないでください。
<table>
<caption>2025 budget allocation by department</caption>
</table>
キャプションは <table> の直接の子要素として(<thead> より前に)配置し、簡潔かつ具体的にしてください。一般的ではない構造の場合は、すべての値を繰り返すのではなく、行と列の構成を説明する短い要約を添えることができます。
<caption>
Availability of holiday accommodation
<span class="table-summary">Locations form row groups. Property types form columns.</span>
</caption>
廃止された HTML の summary 属性を <table> に使用してはいけません。代わりに、表示されるキャプションの内容か、近くにある説明を使用してください。
重大:複数行・列にまたがるヘッダー — scope="colgroup" / scope="rowgroup"
colgroup/rowgroup のスコープ値は、対応するグループがテーブル構造内に実際に存在する場合(対応する <colgroup> または <tbody> の行グループがある場合)に限り使用してください。
<table>
<caption>Quarterly revenue by product line, CAD thousands</caption>
<colgroup><col></colgroup>
<colgroup span="2"></colgroup>
<colgroup span="2"></colgroup>
<thead>
<tr>
<th scope="col" rowspan="2">Product</th>
<th scope="colgroup" colspan="2">First half</th>
<th scope="colgroup" colspan="2">Second half</th>
</tr>
<tr>
<th scope="col">Q1</th><th scope="col">Q2</th>
<th scope="col">Q3</th><th scope="col">Q4</th>
</tr>
</thead>
<tbody>
<tr><th scope="row">Hardware</th><td>1,200</td><td>1,450</td><td>1,100</td><td>1,800</td></tr>
</tbody>
</table>
複数行にまたがる行グループでは、グループヘッダーに rowspan を指定し、scope="rowgroup" を使用してください。プロジェクトで実際に使用する AT の組み合わせでグループ化されたヘッダーをテストしてください。関連付けが分かりにくい場合は、さらに複雑にするのではなく、よりシンプルなテーブルに分割してください。
重大:headers + id を使う場合(まれ)
scope を使うとヘッダーが誤ったセルに適用されるほど複雑なテーブルに限り、使用してください。
<table>
<caption>Accommodation availability</caption>
<thead>
<tr>
<th id="location" scope="col">Location</th>
<th id="studio" scope="col">Studio</th>
</tr>
</thead>
<tbody>
<tr>
<th id="paris" scope="row">Paris</th>
<td headers="paris studio">11</td>
</tr>
</tbody>
</table>
すべての ID はドキュメント内で一意でなければなりません。また、すべての headers トークンは実際のヘッダーセルに対応していなければなりません。headers/id を使う前に、次の方法を検討してください。 1 つのテーブルを複数に分割する、行と列を入れ替える、説明資料をグリッドの外に移動する、入れ子になったヘッダーの階層を減らす、フィルタービューを提供する。技術的に正しくても、1 つのセルを読むのに 3 つまたは 4 つのヘッダーが必要なテーブルは、実際にはアクセシブルでない可能性があります。WebAIM によると、複数階層の行/列ヘッダーは、スクリーンリーダーのユーザーにとって実用上理解しにくい可能性があります。スキーマや列を変更するたびに、headers/id の関連付けを検証してください。
重大:空欄、欠損値、特殊な値
空のセルは曖昧です。ゼロ、該当なし、不明、未報告、または意図的な空欄を意味する可能性があります。区別が重要な場合は、明示的なテキストを使用してください。 測定値がゼロなら 0、該当しない場合は Not applicable、データがない場合は No data、報告されていない場合は Not reported、意図的に値を伏せている場合は Suppressed とします。短縮表記(N/A、em ダッシュ)の意味はキャプションまたは近くの注記で定義してください。スペースに余裕があれば、完全な表記を優先してください。空のセルを埋まっているように見せるために を使用しないでください。推定値、丸め値、暫定値、修正値について説明してください。色やタイポグラフィだけでそれらを識別させないでください。
重大:合計、小計、フッター
合計ラベルがその行の値を示す場合は、ヘッダーとしてマークしてください。
<tfoot>
<tr><th scope="row">Total</th><td>$21,500</td><td>$24,500</td></tr>
</tfoot>
小計を太字、インデント、背景色だけで伝えないでください。表示されるテキスト(「小計」)を含め、ヘッダーとの関連付けを維持してください。合計が動的に計算される場合は、更新状況を適切に示し、エクスポートされる値にも同じ計算が使用されるようにしてください。
中程度:レスポンシブテーブルとリフロー
WCAG 1.4.10 では、データテーブルなど、実際に必要なコンテンツについては二次元スクロールが認められています。この例外はテーブル自体に適用され、周囲のページには適用されません。
<div class="table-scroll" role="region" aria-labelledby="sales-caption" tabindex="0">
<table>
<caption id="sales-caption">Monthly sales by region</caption>
</table>
</div>
.table-scroll { max-inline-size: 100%; overflow: auto; }
.table-scroll:focus-visible { outline: 3px solid currentColor; outline-offset: 3px; }
個別に見つけやすくすることが本当に役立つ場合は、ラベル付き領域を使用してください。すべてのテーブルラッパーをランドマークにしないでください。オーバーフロー領域をキーボードでスクロールできるように tabindex="0" を使用し、フォーカスインジケーターを見えるようにしてください。
table/thead/tbody/tr/th/td の display を block に変更するレスポンシブ CSS は避けてください。 ブラウザーや AT の動作にはばらつきがあり、重複する data-label の内容が実際のヘッダーと食い違う可能性があります。小さい画面ではカード形式のほうが本当に適している場合は、同じデータから実際の代替リストまたは定義リストビューをレンダリングしてください。一度に表示するビューは 1 つにし、すべての値とコントロールを維持し、両方の表示形式をテストしてください。ズーム 200%/400%、長い翻訳文字列、狭いビューポートでテストしてください。
中程度:固定ヘッダーと固定列
thead th {
position: sticky;
inset-block-start: 0;
background: var(--table-header-background);
z-index: 1;
}
元のセマンティックな <th> 要素を維持してください。フォーカス可能なクローンヘッダーを作成しないでください。視覚的なクローンが避けられない場合は、AT から隠し、重複する ID を削除してください。固定コンテンツがフォーカス、見出し、または最初のデータ行を覆わないようにしてください。高倍率ズームとテキスト間隔の上書き設定でテストしてください。
中程度:並べ替え可能な列
並べ替え可能な各列見出しの中にネイティブのボタンを配置し、現在並べ替えられている <th> のみに aria-sort を設定します(ボタンには設定せず、両方にも設定しません)。
<th scope="col" aria-sort="ascending">
<button type="button">
Last name
<span class="sort-icon" aria-hidden="true">▲</span>
</button>
</th>
並べ替えが変更されたら、表示中のページだけでなくデータセット全体を並べ替えます(それ以外の場合は、その旨を明確に示します)。aria-sort を新たに並べ替えられた <th> に移動し、ascending/descending/other を正確に使用します。色だけに頼らず、表示される方向インジケーターを更新します。操作したボタンにキーボードフォーカスを維持し、ヘッダーとデータセルの関連付けを保ちます。<th> 自体にクリックハンドラーを設定して、ボタンの代わりにすることは避けてください。
中程度:フィルタリング、検索、結果件数
<form id="employee-filters">
<label for="department-filter">Department</label>
<select id="department-filter" name="department">
<option value="">All departments</option>
</select>
<button type="submit">Apply filters</button>
</form>
<p id="employee-results" role="status" aria-atomic="true">Showing 24 employees.</p>
フィルタリング後に表示される結果件数を更新します。フォーカスを移動せずに変更する場合は role="status" を使用します。有効なフィルターを表示し、プログラムから判別できるようにします。フィルターを解除する明確な方法を用意し、「結果がありません」を表示して読み上げられるようにします。変更されたセルごとにライブリージョンで読み上げることは避けてください。対象範囲や日付範囲が変更された場合は、キャプションを正確に保ちます。
中程度:ページネーションと大規模なデータセット
数千行をレンダリングしたり仮想化したりするより、ページネーションのほうが堅牢な場合がよくあります。
<nav aria-label="Employees table pages">
<a href="?page=1" aria-current="page">1</a>
<a href="?page=2" rel="next">Next</a>
</nav>
aria-current="page" で現在のページを示します。URL に基づくナビゲーションにはリンクを、ページ内の状態変更にはボタンを使用します。並べ替え/フィルターのパラメーターを維持し、表示範囲と合計を示します(「842 行中 51~100 行」)。予測可能で役立つ場合にのみ、フォーカスを移動します。「さらに読み込む」コントロールには、明確な名前、結果の更新、予測可能なフォーカス動作が必要です。
仮想化(スクロール中にデータセットの一部だけをレンダリングすること)は、ページ内検索、テーブルナビゲーション、行数、フォーカス、読み進める際の連続性を損なう可能性があります。タスクを満たせる場合は、ページネーションを優先してください。仮想化が必要な場合は、正確な行数と列数を公開し、レンダリングされた項目の正しいインデックスを公開します。ユーザーが操作している行を、ユーザーの操作中に再利用して取り除いてはいけません。項目が DOM から外れても、選択/編集状態を維持し、ヘッダーを正しく関連付け、ズーム/テキストサイズ変更/可変行高をサポートします。視覚的なスクロールだけでなく、スクリーンリーダーで連続して読み進める操作をテストしてください。aria-rowcount があるだけで、数千行がアクセシブルだと主張してはいけません。
重大:行の選択と行のアクション
<tr> 全体を、名前のないクリック可能なコントロールにしてはいけません。セル内に実際のチェックボックス、リンク、またはボタンを配置してください。
<p id="select-invoice" class="visually-hidden">Select invoice</p>
<tr>
<td><input type="checkbox" name="invoice" value="1042" aria-labelledby="select-invoice invoice-1042"></td>
<th id="invoice-1042" scope="row">1042</th>
<td>$1,240</td>
</tr>
チェックボックスの計算名は「請求書 1042 を選択」になります。選択状態をプログラムから判別できるようにし、色だけに頼らず視覚的にも区別できるようにします。行ごとに繰り返されるアクションには、それぞれのアクセシブルな名前に行の識別子を含めてください。「表示」や「編集」とだけ読み上げられるリンクが何十個も並ぶことは避けてください。
重大:フォームとテーブル内での編集
すべての入力欄に、行/列のコンテキストを十分に含む固有のラベルが必要です。
<tr>
<th scope="row">Widget A</th>
<td>
<label class="visually-hidden" for="widget-a-quantity">Quantity for Widget A</label>
<input id="widget-a-quantity" name="widget-a-quantity" type="number" min="0" value="2">
</td>
</tr>
検証エラーを該当する入力欄に関連付けます。エラー時に入力欄を行のコンテキストから切り離さず、検証後もユーザーが入力した値を保持し、保存/キャンセル/元に戻す操作を明示します。ユーザーに警告し、元に戻せるようにしていない限り、フォーカス移動時に自動保存してはいけません。多くのセルをまたいだスプレッドシートのようなナビゲーション/編集が必要な場合は、データテーブルに場当たり的なキーボード操作を追加するのではなく、ARIA グリッドの採用を検討してください。
中程度:展開可能な行
<tr>
<th scope="row">Invoice 1042</th>
<td>$1,240</td>
<td>
<button type="button" aria-expanded="false" aria-controls="invoice-1042-details">
Show details for invoice 1042
</button>
</td>
</tr>
<tr id="invoice-1042-details" hidden>
<td colspan="3">
<h3>Invoice 1042 details</h3>
<p>Issued 4 March 2025. Payment is due 3 April 2025.</p>
</td>
</tr>
aria-expanded、ボタンのテキスト、hidden をまとめて更新します。ユーザーの操作が開示されたコンテンツへの移動を明確に求めている場合を除き、ボタンにフォーカスを維持します。
中程度:色、コントラスト、強制カラー
ゼブラストライプは補助的なものであり、それだけでは不十分です。期限超過/選択済み/無効/変更済みのデータを示す唯一の方法として行の色を使わないでください。可視テキスト、アイコン、またはパターンを追加してください。テーブルのテキストと、必要な非テキスト要素(フォーカスインジケーター、フォームコントロールの境界線、並べ替え/状態アイコン)が、該当するコントラスト要件を満たすようにしてください。装飾的なセルの境界線やゼブラストライプには、自動的に 3:1 のコントラスト比が必要になるわけではありません。
tbody tr:nth-child(even) { background: var(--table-stripe-background); }
@media (forced-colors: active) {
th, td { border-block-end: 1px solid CanvasText; }
.sort-icon { color: CanvasText; }
}
サポートするすべてのテーマと強制カラーモードで、選択行、無効なセル、フォーカス、ホバー、並べ替え、固定ヘッダーをテストしてください。
データテーブルと ARIA グリッド
ネイティブの <table> は読み取りや比較をサポートし、通常、セルを Tab キーのフォーカス順序には含めません。スクリーンリーダーには独自のテーブルナビゲーション機能があります。role="grid" は、フォーカス管理、矢印キーによるナビゲーション、選択、編集、行/列構造の公開が期待される複合ウィジェットです。グリッドを使うのは、次の場合のみにしてください。ユーザーがスプレッドシートのようなセルのナビゲーション/編集を必要としていること、操作モデルが文書化され、完全に実装されていること、意図したセル/子孫要素のみが Tab キーのフォーカス順序に含まれること、矢印キー/Home/End が予測どおりに動作すること、行/列の位置と状態が正確であること、関連する AT でテストされていること。テーブルをよりインタラクティブに見せるためだけに role="grid" を追加しないでください。並べ替え/フィルターボタンがあるだけでは、テーブルはグリッドになりません。 ネイティブの <table> を優先してください。
レイアウトテーブル — 対応方法
可能な限り削除して CSS を使用してください。レガシーなレイアウトテーブルをまだ削除できない場合:
<table role="presentation">
<tr><td></td></tr>
</table>
その中では <th>、<caption>、テーブル固有のナビゲーションを使用しないでください。コンテンツが直線的に読み上げられる、意味のある DOM 順序になっていることを確認してください。フォーム/見出し/リストがそれぞれのネイティブなセマンティクスを維持していることを確認してください。テーブルにフォーカス可能な状態を設定したり、テーブル固有の ARIA を付与したりしないでください。ここでは role="none" は role="presentation" と同等です。これは一時的な修正として扱い、新たなレイアウトパターンとして採用しないでください。
印刷とエクスポート
@media print {
thead { display: table-header-group; }
tfoot { display: table-footer-group; }
tr { break-inside: avoid; }
}
エクスポートした PDF/スプレッドシート/ドキュメント/プレゼンテーションファイルでは、テーブル構造とヘッダーの関連付けを維持してください。タイトル/キャプションを含め、ページ/シートをまたいでヘッダーを繰り返し、単位/フィルター/ソース/日付範囲を維持し、特殊な値や略語を説明してください。エクスポートした形式を、それぞれのアクセシビリティツールで個別にテストしてください。アクセシブルな HTML だからといって、エクスポートしたファイルもアクセシブルであるとは限りません。 出力形式ごとに個別にテストし、修正してください。
CMS とフレームワークに関する注意事項
Drupal: CKEditor のテーブルプラグインは、<caption> と scope 属性を必須にするよう設定してください。
Drupal Accessibility Coding Standards
では、コントリビュートされたモジュール/テーマに WCAG 2.1 AA を求めています。
WordPress/その他の CMS: ブロックエディターは、<caption> や scope のないテーブルを生成することがよくあります。CMS が生成するマークアップを監査し、エディターを設定するか、出力を後処理して不足している属性を追加してください。
生成されるテーブル(データグリッドライブラリ、DataTables.js、AG Grid): ライブラリが <th scope="col">、<caption>、<thead> を出力することを確認してください。これらの多くはデフォルトでは出力しません。正確なバージョンを設定またはテストし、作成者が実際のヘッダーセルを作成できること、キャプション/要約を追加できること、scope/headers/一意の ID が保持されること、サニタイズによって必要な属性が削除されないこと、エクスポート形式で構造が維持されることを確認してください。
テスト
- 構造: コンテンツが実際に表形式であることを確認します。すべての行/列/行グループ/列グループの見出しを特定し、各データセルについてユーザーに必要な見出しを確認します。
scope/headersによってそれらの正確な関連付けが実現されていることを確認し、キャプション、単位、出典、特殊な値の定義をチェックします。並べ替え後や再レンダリング後に、IDとheadersの参照が有効であることを検証します - キーボード/視覚: ポインターを使わずに、並べ替え/フィルタリング/ページネーション/選択/編集/開閉を操作します。フォーカスが表示されたままで、予期せず移動しないことを確認します。横幅の広い表をキーボードでスクロールします。200%/400%のズームと狭いビューポートをテストします。すべてのテーマ、強制カラーモード、印刷、エクスポート形式をテストします
- AT: 表に移動し、名前と寸法が有用であることを確認します。代表的なセルを順に移動して、見出しが読み上げられることを検証します。グループ化された見出し/複数の行や列にまたがる見出し/不規則な見出しを十分にテストします。並べ替えの状態、選択した行、展開した行、入力ラベル、エラー、結果の状態を確認します
- 自動テスト: 見出しの不足、無効なARIA、重複したID、空のキャプション、コントラスト、フォーカスの問題の一部は検出できますが、通常は、文脈上セルが見出しかどうか、関連付けが意図した関係を表しているか、複雑な表を簡素化すべきかは判断できません。引き続き、セルを1つずつ手動で確認する必要があります。
よくある失敗
| 失敗 | 修正 |
|---|---|
太字の<td>要素で見出しを視覚的に模倣する | 正しい関連付けを持つセマンティックな<th>を使用します |
「すべての<th>にscopeが必要」とWCAGの絶対的な要件として述べる | 方向性が重要な場合は、堅牢なパターンとして明示的なscopeを使用します。基準を誤って説明しないでください |
| 「適合のためにすべての表にキャプションが必要」と絶対的な要件として述べる | 原則としてキャプションを使用します。他の検証済みの関連付けによって、単純な表を特定できる場合があることも認識してください |
対応する<colgroup>がないのにscope="colgroup"を使用する | マークアップで列グループを定義します |
headersの値が現在のIDと一致しなくなっている | 現在のスキーマから関連付けを再生成し、検証します |
空のセルに や説明のないダッシュを使用する | ゼロ、該当なし、欠損、非表示、または別の正確な意味を明示します |
レスポンシブCSSですべての表要素をdisplay: blockに変更する | 表のセマンティクスを維持します。包含されたオーバーフロー、または実際の代替ビューを使用します |
| すべてのスクロール用ラッパーをランドマークリージョンにする | 別途見つけやすくすることが有用な場合にのみ、名前付きリージョンを追加します |
aria-sortを並べ替えボタンに設定する | 現在並べ替えられている<th>のみに設定します |
| 説明なしに、表示中のページだけを並べ替える | 結果セット全体を並べ替えるか、対象範囲を明確に説明します |
| 行全体をクリック可能にする | セル内に、名前の付いたネイティブのリンク、ボタン、またはチェックボックスを配置します |
| 繰り返されるコントロールが「表示」/「編集」とだけ読み上げられる | アクセシブルな各名前に行の識別子を含めます |
グリッド用のキーボード操作モデルを実装せずにrole="grid"を追加する | ネイティブの表を維持するか、複合ウィジェットを完全に実装します |
| フォーカスを含む仮想行が消える | フォーカスと状態を維持するか、ページネーションを使用します |
| HTMLの表は問題ないが、エクスポートしたPDFでは見出しが失われる | 出力形式ごとに個別にテストし、問題を修正します |
完了の定義チェックリスト
- コンテンツに行と列の関係性が必要であり、レイアウト用の表ではありません
- 機能を持つすべての見出しが、適切な関連付けを持つ
<th>になっています - 表には有用な名前があり、通常は
<caption>(または検証済みの代替手段)で示されています - 複雑な構造には、簡潔で見つけやすい説明があります
-
scope、グループ、スパン、ID、headersの参照が現在のデータと一致しています - 複雑さが理解の妨げになる場合は、表を簡素化するか分割しています
- 空欄/欠損/ゼロ/非表示/推定の値を区別できます
- 単位、日付、通貨、略語が明確です
- 幅の広い表は、キーボードで操作できる領域内でスクロールできます
- レスポンシブ表示でも表のセマンティクスを維持するか、実質的に同等の表示を提供しています
- スティッキーヘッダーがセマンティクスを重複させたり、コンテンツを隠したりしません
- 並べ替え状態は適切な
<th>のみに設定され、並べ替えコントロールはキーボードで操作できます - フィルタリング/ページネーション/選択/編集/開示には、名前が付いたネイティブコントロールを使用しています
- 意味や状態を示す手段が色だけに依存していません
-
role="grid"は、完全で検証済みのグリッド操作モデルがある場合にのみ使用しています - 仮想化(使用している場合)でも、件数、位置、フォーカス、読み上げの連続性を維持しています
- 印刷およびエクスポートでも、構造と関係性が維持されています
- NVDA+Chrome、JAWS+Chrome、VoiceOver+Safariでテスト済みです
主なWCAG基準
- 1.3.1 情報及び関係性(A)— 見出しがない、または適切に関連付けられていない場合は重大
- 1.3.2 意味のある順序(A)
- 1.4.1 色の使用(A)
- 1.4.3 コントラスト(最低限)(AA)
- 1.4.10 リフロー(AA)
- 1.4.11 非テキストのコントラスト(AA)
- 2.1.1 キーボード(A)
- 2.4.3 フォーカス順序(A)
- 2.5.3 名前のラベル(A)
- 2.5.8 ターゲットのサイズ(最低限)(AA)
- 3.3.1 エラーの特定(A)— 編集可能な表
- 4.1.2 名前、役割、値(A)
- 4.1.3 ステータスメッセージ(AA)
参考資料
- ベストプラクティスの完全ガイド
- WAIの表チュートリアル
- WebAIM:アクセシブルな表の作成
- WAI-ARIA APGの並べ替え可能な表の例
- WAI-ARIA APGのグリッドパターン
- Drupalのアクセシビリティコーディング標準
標準の見通し: これらのルールはWCAG 2.2 AAを対象としています。WCAG 3.0で表のアクセシビリティ要件に大きな変更が加わる予定はありません。 こちらを確認してください:https://www.w3.org/TR/wcag-3.0/