トピックを検索
divやアイコン、手入力の番号で作った見た目だけのリスト
プランのカードで、特長をチェックアイコン付きのdivで、始め方の手順を番号を手入力した段落で表しているため、スクリーンリーダーでは、リストでも件数もない、ばらばらの行として読まれ、移動もスキップもできません。
<div class="feature"><svg class="icon-check" …>プロジェクト数無制限</div> 問題
スクリーンリーダー利用者には、プランの特長と手順が、件数も終わりもないばらばらの行として聞こえ、そこへ移動することも、読み飛ばすこともできません。
料金ページに、チームプランのカードがあります。プラン名の下に4つの特長が並び、それぞれの前に緑のチェックマークがあります。プロジェクト数無制限、50 GBのストレージ、共有カレンダー、優先サポートです。その下の「始め方」には、プランを使い始めるための番号付きの手順が3つあります。見える人には、4つの特長のリストと、3つの手順のリストに見えます。スクリーンリーダー利用者には、違って聞こえます。カードを上から読むと、「チームプラン 見出しレベル3」の後、特長が1行ずつ読まれます。最初の項目の前にリストの始まりや長さを伝えるものはなく、最後の項目の後にも終わりを伝えるものはありません。NVDAやJAWSで次のリストへ移動するLキーを押すと、「次のリストはありません」と返ってきます。手順は番号付きで読まれますが、やはり別々の行で、3項目のリストにはなりません。
1.3.1は、見て分かる構造をコードでも伝えることを求めます。チェックマーク、行のそろえ方、番号のすべてが、これらの行がひとまとまりの項目であり、いくつあるかを示しています。ところがマークアップは、次の2つの形で、そのことを何も伝えていません。
- 特長は、インラインSVGのチェックマーク付きの
divです。装飾のアイコンとして正しくスクリーンリーダーから隠されているため、残るのは無関係な4つのテキストのかたまりです。 - 手順は、番号をテキストに手入力した
pです。番号は読まれますが、3つの段落はまとまっていないため、項目数もなく、リスト移動で見つかるものもありません。順番は聞いて分かるため、手入力の番号を1.3.1の「テキストで提供されている」場合として認める評価者もいます。しかし、Trusted Testerの手順や多くの診断では認めていません。まとまりと項目数は、やはり伝わらないためです。
カードはどのブラウザーでも正しく見えるため、目で確かめる人は誰も問題に気づきません。影響を受けるのは、マークアップからページの構造を知る人です。
10グループ中2グループに影響
axe のリストのルールが確かめるのは、すでにあるリストのマークアップです。ul と項目の間の div(list)や、リストの外にある li(listitem)を見つけます。リストのマークアップがまったくないカードでは確かめるものがないため、この例の2つの形はどちらも axe のチェックを通ります。EaseWebの診断は、手入力の行頭記号や連番で始まる行と、リストの項目でない要素にCSSで描いた行頭記号を報告します。アイコンで始まる行は、リンクやツールバーの並びである場合もあるため、報告せずに確認の対象にします。AIによる修正には、別の誤りがあります。手順を ol で囲んで手入力の番号を残すと、どの手順も「1. 1. チームを作成します。」と二重に読まれます。入れ物に role="list" を付けても、各項目を包む div が残っていれば、項目のないリストになります。行のまとまりがリストのつもりか、順番に意味があるかは、ページの表示と照らし合わせて判断する必要があります。
試してみる
プランのカードを聞いてから、スクリーンリーダー利用者と同じ方法でリストへ移動してみてください。
パネルには、NVDAやJAWSがカードを上から読んだ内容が出ます。「Lキー」は次のリストへ移動するキーです。リストの始まり、長さ、終わりを伝えるものはありますか?「問題2」は、番号を段落に手入力した手順です。
問題あり 修正できますか?
カードを上から読むと、スクリーンリーダーの読み上げ:
チームプラン 見出しレベル3プロジェクト数無制限50 GBのストレージ共有カレンダー優先サポート再現デモです。「問題あり」は意図的にアクセシブルでない状態にしています。
修正方法
項目のまとまりは、ulとol、またはリストのロールでリストにし、順番のある手順には番号を一度だけ付けます。
- 1リストに見えるものはリストにする。ul、ol、dl、またはrole="listitem"の項目を持つrole="list"を使う。
- 2順番に意味があるときは番号付きリストにし、番号は一度だけ付ける。
- 3リストの直下には項目だけを置き、リストを上書きするロールを付けない。
アイコンで描いた特長
<h3>チームプラン</h3><div class="features"> <div class="feature"><svg class="icon-check" aria-hidden="true">…</svg>プロジェクト数無制限</div> <div class="feature"><svg class="icon-check" aria-hidden="true">…</svg>50 GBのストレージ</div> <div class="feature"><svg class="icon-check" aria-hidden="true">…</svg>共有カレンダー</div> <div class="feature"><svg class="icon-check" aria-hidden="true">…</svg>優先サポート</div></div>Ulとol要素
<h3>チームプラン</h3><ul class="features"> <li><svg class="icon-check" aria-hidden="true">…</svg>プロジェクト数無制限</li> <li><svg class="icon-check" aria-hidden="true">…</svg>50 GBのストレージ</li> <li><svg class="icon-check" aria-hidden="true">…</svg>共有カレンダー</li> <li><svg class="icon-check" aria-hidden="true">…</svg>優先サポート</li></ul> <h3>始め方</h3><ol class="steps"> <li>チームを作成します。</li> <li>最大10人を招待します。</li> <li>カレンダーを連携します。</li></ol>この方法を選ぶ理由:まずHTMLの要素を使う
画面ではチェックマークがリストを作っていますが、リストらしさはそれだけで、しかもスクリーンリーダーからは隠されています。4つの div には関係がないため、たまたま続いている4行として読まれます。
特長は番号なしリスト、手順は番号付きリストになり、スクリーンリーダーは項目を読む前に「リスト 4項目」「リスト 3項目」と伝え、終わりも伝えます。Lキーを押すと、どちらのリストでも止まります。番号は ol が付けるため、手入力の番号はなくなり、手順を足しても残りを書き直す必要はありません。チェックマークは残し、標準の行頭記号はCSSで消すため、カードの見た目は変わりません。
どちらの方法でも、それぞれのまとまりが正しい項目数のリストになり、1.3.1を満たします。マークアップを変えられる場所では、ul と ol を使ってください。そろえて保つ属性がなく同じ働きをし、手順の番号は ol が付け、スクリーンリーダーに限らず、ページを読むすべてのツールがリストとして扱います。ロールは、コンポーネントライブラリのグリッドのように、属性は足せても要素は変えられない場合に使い、変えられるようになったらリストの要素に置き換えます。
CSSで行頭記号を消すのは問題ありませんが、例外が1つあります。Safariは以前から、CSSで記号を消した(list-style: none)ul や ol を、nav の中にない限り、VoiceOverにリストとして伝えません。プランの特長のように項目数が大切な場合は、その ul に role="list" を加えます。ほかのブラウザーでは不要ですが害はないため、記号が見えているリストには付けません。
リストのマークアップは、正しく保たれている間だけ役に立ちます。正しく作ったリストも、次のことで壊れます。
- リストと項目の間に包む要素がある:
ulとolの直下に置けるのはliだけ。各項目をdivで包むコンポーネントは、そのdivをliの中に移す。 - 項目だけがリストの外にある:条件付きの描画で
ulが消えてliだけが残ると、どこにも属さない項目になる。 - 用語と説明が
dlの外にある:「ストレージ:50 GB」のような組には、dtとddを持つdlを使う。各組は1つのdivで包んでもよく、それ以外は直下に置かない。 - リストにロールが付いている:
ulにrole="presentation"やrole="navigation"を付けると、リストではなくなる。ナビゲーションのリストは、nav要素の中に置く。
リストの種類は、見た目ではなく内容で選びます。手順や順位のように順番に意味があるときは ol、ないときは、デザインに番号が付いていても ul を使います。どちらもCSSで自由に装飾できます。チェックマーク、独自のカウンター、横並びにしても、リストのままです。入れ子のリストは、属する li の中に置き、項目の間には置きません。
すべてのまとまりをリストにする必要はありません。1つだけの項目、横に並んだ2つのリンク、3つのものを挙げる文は、そのままで構いません。カードの並び、ナビゲーションのリンク、検索結果は、リストにすると読み始める前に量が分かるため、役に立ちます。
手入力の記号や番号は、たいてい文書から貼り付けたCMSのテキストから生まれます。エディターのリストのボタンを使えるようにし、「1.」や「•」で始まる行を、入力した時点でリストに変換させます。
AI コーディングアシスタントで修正しますか? このガイドを Markdown で取得
修正の確認
マウスを使わない4つの確認
確認方法: スクリーンリーダー
OS、ブラウザーと支援技術のバージョン、ビルド、実施日、各手順の実際の結果を記録してください。共通のリストのコンポーネント、CMSのエディター、記号を消すスタイルを変更した際は、再度確認します。
制限
このサンプルは、どのアプリケーションでも同じ結果になることを保証するものではありません。クラス名とアイコン内の … は仮のものです。スクリーンリーダーによって「リスト 4項目」「4項目のリスト」など言い方が異なるため、正確な言い回しではなく、項目数と終わりが伝わるかを確認してください。このガイドは、リストとして表示している内容がリストとしてマークアップされているかを扱います。表、見出し、ドラッグで並べ替えるリストは扱いません。実際に使用する支援技術で、操作全体を確認してください。
よくある問題を再現した学習用のサンプルです。実在のクライアントの診断結果ではありません。コードは出発点となる実装例のため、実際の製品でも確認してください。ここでは支援技術でのテスト結果は報告していません。
参考資料
- WCAG Understanding: info-and-relationships(新しいタブで開きます)
- WCAG Technique H48(新しいタブで開きます)
- developer.mozilla.org: ul(新しいタブで開きます)
- developer.mozilla.org: ol(新しいタブで開きます)
- developer.mozilla.org: list_role(新しいタブで開きます)
- dequeuniversity.com: list(新しいタブで開きます)
- dequeuniversity.com: listitem(新しいタブで開きます)
- dequeuniversity.com: definition-list(新しいタブで開きます)
- dequeuniversity.com: dlitem(新しいタブで開きます)
コードを更新しても、使いやすさを保つために
ガイドの内容を、コーディングエージェントやCIで使える開発ルールにまとめます。更新後は、キーボードとスクリーンリーダーで再テストし、問題が再発していないか確認します。