トピックを検索
見出しが太字だけのデータ表
見出し行は見出しらしく装飾されていますが、すべてのセルがtdのため、値と行や列の関係がコードにありません。
問題
スクリーンリーダー利用者には、数字がどの行と列のものか伝わりません。
料金ページで、プランを表にして比べています。一番上の行には太字で「プラン」「月額」「年額」とあり、その下の各行はプラン名から始まります。目で見る人は、上と左を見れば数字の意味が分かります。スクリーンリーダーでセルを移動すると、「$12」「$120」「$30」「$300」と値だけが読まれます。「$30」がTeamプランの月額だと知るには、列の先頭と行の先頭まで戻り、その両方を覚えておく必要があります。
すべてのセルが td です。見出し行はクラスで、プラン名は最初の列へのスタイルで太字にしているだけです。太字は見た目の関係で、マークアップには含まれません。WCAG 1.3.1「情報及び関係性」は、見た目で示した構造をコードでも伝えることを求めています。データ表の構造の中心は、どの見出しがどのセルにかかるかです。th もARIAの見出しのロールもないため、ブラウザーは関係を伝えられず、スクリーンリーダーも値と一緒に見出しを読めません。
この例の表は小さく、数えて戻るのは手間がかかる程度です。時刻表や成績表、十数列の比較表では、表の形を記憶の中で組み立てる必要があり、一度間違えると別の料金や時刻を読み取ってしまいます。
10グループ中1グループに影響
- 全盲 (影響あり)
- 弱視 (影響なし)
- 色覚 (影響なし)
- ろう (影響なし)
- 難聴 (影響なし)
- 発話 (影響なし)
- 手の操作 (影響なし)
- 届く範囲・力 (影響なし)
- 認知 (影響なし)
- 光過敏 (影響なし)
- 視覚を使わない スクリーンリーダーで表を移動すると値だけが読まれるため、「30」がどのプランのどの期間の料金か、上の行まで戻って数えないと分かりません。
自動チェックは、表に th がないことは指摘できますが、どのセルが見出しであるべきかは判断できません。違うものを見出しにした th があると、何も報告しないツールもあります。scope の向きが正しいか、並べ替えで作り直した行が見出しと合っているかも確認できません。AIによるコード生成では、div を並べて表のように見せたり、role="table" だけを付けて行やセルのロールを省いたりすることがよくあります。スクリーンリーダーでセルを順に読み、目で見て使う見出しが各値と一緒に読まれるかを確かめてください。
試してみる
Tabキーで料金を順に移動してください。
Tabキーの1回が、スクリーンリーダーで次のセルへ移る操作の代わりです。下の欄に読み上げが出ます。各料金が何の料金か分かりますか?
問題あり 修正できますか?
| プラン | 月額 | 年額 |
| Starter | $12 | $120 |
| Team | $30 | $300 |
スクリーンリーダーの読み上げ: (Tabで料金へ移動)
再現デモです。「問題あり」は意図的にアクセシブルでない状態にしています。
修正方法
見出しのセルを見出しとしてマークアップし、どの方向の見出しかを示します。
- 1見出しのセルはすべて
thにするか、構造のそろったARIAの表でcolumnheaderかrowheaderにする。 - 2各
thにscopeを付けるか、各tdにheadersを付ける。一つの表で両方は使わない。 - 3レイアウトに表を使わず、データ表には
role="presentation"を付けない。
<table class="prices"> <tr class="head"> <td>Plan</td> <td>Monthly</td> <td>Yearly</td> </tr> <tr> <td class="plan">Starter</td> <td>$12</td> <td>$120</td> </tr> <tr> <td class="plan">Team</td> <td>$30</td> <td>$300</td> </tr></table>この方法を選ぶ理由:まずHTMLの要素を使う
head と plan のクラスは文字を太くするだけです。すべてのセルがデータのため、スクリーンリーダーは「$30」とだけ読みます。
見出しをすべて th にし、scope で列の見出しか行の見出しかを示します。そのセルでは「Team、Monthly、$30」と読まれ、列を下へ移動すると、変わった行の見出しだけが繰り返されます。th は初めから太字のため、元のクラスは不要です。
この表では、三つとも1.3.1を満たします。scope を付けた th を使ってください。ほかの二つと同じ役割を最も少ないコードで果たし、合わせるべきidもなく、どのスクリーンリーダーやブラウザーの閲覧モードでも動きます。headers とidは、scope ではどの見出しがかかるか表せないほど不規則な表にだけ使い、ARIAのロールは表の要素を出力できない場合にだけ使います。ロールを使う場合は、一つ抜けるだけで格子が気づかないうちに壊れるため、すべてそろっているか確認してください。
マークアップを正しくした後も、見出しの働きが変わる場面があります。
scopeのないth:見出し行が一つの単純な表では、ブラウザーが向きを推測します。ただしscopeを付けても手間はかからず、後で行の見出しが加わっても正しく働きます。- レスポンシブな表:表の要素に
display: blockやgridを指定すると、ブラウザーによっては表の意味が失われます。狭い画面のレイアウトもスクリーンリーダーで確認するか、表はそのままにして、名前を付けたフォーカス可能な領域の中で横にスクロールさせます。 - 並べ替えと絞り込み:本体を作り直すときも、行の
thを残します。並べ替えた列はaria-sortで示します。これは別のトピックです。 - レイアウト用の表:配置のためだけの表には、
thやcaptionを使いません。role="presentation"を付けるか、CSSのレイアウトに置き換えます。
caption は表に名前を付け、表を移動する人が表を区別できるようにします。別のガイドで扱いますが、同じコンポーネントに含めてください。
AI コーディングアシスタントで修正しますか? このガイドを Markdown で取得
修正の確認
マウスを使わない5つの確認
確認方法: スクリーンリーダー、キーボード、ズーム
OS、ブラウザーと支援技術のバージョン、ビルド、実施日、各手順の実際の結果を記録してください。表のコンポーネントを変更した際は、再度確認します。
制限
このサンプルは、どの表でも同じ結果になることを保証するものではありません。見出しをどこまで、いつ繰り返して読むかは、スクリーンリーダーによって異なります。見出しが何段にも重なる表は、マークアップが正しくても理解しにくいため、データが許す場合は単純な表に分けてください。
よくある問題を再現した学習用のサンプルです。実在のクライアントの診断結果ではありません。コードは出発点となる実装例のため、実際の製品でも確認してください。ここでは支援技術でのテスト結果は報告していません。
コードを更新しても、使いやすさを保つために
ガイドの内容を、コーディングエージェントやCIで使える開発ルールにまとめます。更新後は、キーボードとスクリーンリーダーで再テストし、問題が再発していないか確認します。