トピックを検索
件数が読み上げられない検索・絞り込み結果
入力のたびに件数の行が書き換わりますが、その行がライブリージョンではないため、スクリーンリーダーは件数を読み上げません。
count.textContent = countText(products.length, words); 問題
スクリーンリーダーの利用者は、検索語を入力したり絞り込みにチェックを入れたりしても、結果が変わったのか、何件あるのか、一致しなかったのかが分かりません。
キッチン用品の小さなショップが、検索欄の下に6件の商品を並べ、その上に「すべての商品(6件)」と表示しています。検索は入力しながら動き、手を止めて少しすると、リストが描き直され、行が「「エプロン」の検索結果:3件」に変わります。画面が見える人は、リストが短くなるのを見て件数を読みます。スクリーンリーダーの利用者は「エプロン」と入力して手を止めても、入力した文字のほかは何も聞こえません。検索が動いたのか、エプロンが3件あったのか1件もなかったのか、Enterキーを押すべきなのかが分かりません。そこで検索欄を離れ、リストを一つずつたどって数えます。何も一致しないと行がそう伝えますが、それも聞こえません。
「「エプロン」の検索結果:3件」はステータスメッセージです。利用者の操作の結果を伝え、フォーカスを受け取りません。達成基準4.1.3は、こうしたメッセージを役割やプロパティによって支援技術に伝え、フォーカスを動かさずに読み上げられるようにすることを求めています。W3Cがこの基準で最初に挙げる例も、これに近いものです。検索ボタンの下に結果が表示され、その先頭近くに何件返ったかを示す行があります。この例では、その行がただの p です。画面上の文言は変わっても、支援技術に変化を読むよう伝えるものがありません。検索の結果は見えていても、聞こえません。
入力しながら動く検索は、リストを見ている人に向けて作られています。スマートフォンでは、リストが画面キーボードの下に隠れることが多く、画面が見える人も件数の行に頼ります。それを見ていない人には、何も伝わりません。
10グループ中2グループに影響
スキャンはページを読み込み、マークアップの中に「すべての商品(6件)」を見つけます。検索欄に入力はしないため、行が変わる様子は見えず、その行が結果を伝えるものだということもHTMLからは分かりません。検索結果をアクセシブルにするよう頼まれたAIアシスタントは、結果のリスト自体に aria-live を付けることがよくあります。すると、手を止めるたびに商品名がすべて読み上げられるか、フレームワークがリストを置き換える場合は何も読まれません。内容と一緒に現れた領域は読み上げられないためです。結果へフォーカスを移す例もありますが、語の途中で検索欄からカーソルが抜けてしまいます。検索しながらスクリーンリーダーで聞いて、初めて分かります。
試してみる
「エプロン」で検索して手を止め、読み上げを聞いてください。
下の欄に、検索のたびのスクリーンリーダーの読み上げが出ます。商品の件数は聞こえますか?何も一致しない語も試してください。
問題あり 修正できますか?
すべての商品(6件)
- リネンのエプロン
- 帆布のエプロン
- 子ども用エプロン
- ティータオル3枚組
- オーブンミトン
- パン型
スクリーンリーダーの読み上げ:
(検索欄に入力して、手を止めてください)
修正方法
検索より前からあるステータス領域に、結果がそろってから件数を書き込みます。
- 1ステータス領域はページと一緒に表示し、結果と一緒に作り直される部分の外に置く。
- 2件数は入力が止まり結果がそろってから伝え、一致しないときも伝える。
- 3フォーカスは検索欄から動かさず、結果のリストにaria-liveを付けない。
<label for="q">商品を検索</label><input type="search" id="q"><p id="result-count">すべての商品(6件)</p><ul id="results">…</ul>見えている件数をステータス領域にする
<label for="q">商品を検索</label><input type="search" id="q"><p id="result-count" role="status">すべての商品(6件)</p><ul id="results">…</ul>文言も位置も正しいのですが、p はライブリージョンではないため、変化は描かれても読み上げられません。
件数の行は、描き直されるリストの外に最初からあるため、role="status" を付けるだけで、ブラウザーが最初から見ている控えめなライブリージョンになります。手を止めて少しすると、スクリーンリーダーは読み上げ中の内容を終えてから「「エプロン」の検索結果:3件」と読みます。カーソルは検索欄に残ります。聞こえる内容は、いつも見えている行と同じです。新しいコードは属性と say だけです。ただし、件数の行そのものが検索のたびに残る場合に限ります。結果と一緒に行も作り直すページでは、次の方法を使ってください。
どちらも、フォーカスを動かさずに結果の件数を伝えます。件数の行が検索のたびに残るなら、見えている件数をステータス領域にしてください。すでにある要素に属性を一つ付けるだけで、聞こえる内容が見える内容からずれることもありません。隠した領域が合うのは、件数が結果と一緒に作り直され、それを変えられない場合です。たとえば他社の検索ウィジェットや、まるごと再描画される結果のコンポーネントです。その代わり、同じ文言をもう一か所、そろえて保つ必要があります。
伝えるタイミング。 適切なタイミングは、検索の始まり方によって変わります。
- 入力しながら動く検索:キーを押すたびではなく、入力が止まり、結果がそろったときに伝えます。0.5秒ほど待てば、速く入力する人にも件数は5回ではなく一度だけ聞こえます。
- チェックしたらすぐ反映される絞り込み:その変更の結果がそろったときに伝えます。スクリーンリーダーは先にチェックボックス自体の状態を読み、そのあとに件数を読みます。
- 「適用」ボタンのある絞り込みパネル:「適用」を押したあとに伝えます。フォーカスはボタンに残すか、パネルが閉じる場合はパネルを開いたボタンに戻します。
- 新しいページを読み込む検索:この場合、件数はステータスメッセージではありません。ページのタイトルと見出しに入れます(「エプロンの検索結果 3件」)。ページの読み込み時に読まれます。
作り直される部分の外に置きます。 コンポーネントのフレームワークでは、領域をレイアウトか、検索コンポーネントのうち表示され続ける部分に置きます。キー付きのブロック、{#if}、結果と一緒に置き換わるリストの中には置きません。メッセージと一緒に作られる領域は、書き方が違うだけで同じ失敗です。
伝えるのは件数で、リストではありません。 結果のリストに aria-live を付けないでください。手を止めるたびに商品名がすべて読まれるか、リストが置き換わって何も読まれないかのどちらかで、知りたかった件数が埋もれます。件数の行だけで十分です。利用者は準備ができたらリストへ移動できます。
0件には言葉と次の手を。 「商品が見つかりませんでした」だけでは、利用者は行き詰まります。別の語や、絞り込みを減らすことなど、次に試すことを伝えます。検索が表記ゆれを直す場合(「エプロンの結果を表示しています」)は、同じメッセージに含めます。
同じ文言が続くとき。 検索語のあとに空白を入れたり、何も変わらない絞り込みにチェックを入れたりすると、同じ文言がもう一度書き込まれます。領域の文言が変わらないと、何も読まないスクリーンリーダーがあります。say は先に領域を空にし、少し待ってから書き込むため、毎回件数が読まれます。見えている行では、文言が0.1秒ほど消えますが、ほとんど気づかれません。
時間のかかる検索。 結果が出るまでに少しかかる場合は、同じ領域に「検索中…」と書き込み、そのあとに件数を書き込みます。すぐに結果が出る検索では書き込まないでください。雑音が増えるだけです。読み込み中のメッセージについては、読み上げられない読み込み中の表示を参照してください。
控えめに伝えます。 role="status" は、スクリーンリーダーが読み終えるのを待ってから伝えるため、件数に合っています。role="alert" や aria-live="assertive" は使わないでください。入力した文字の読み上げに割り込んでしまいます。
修正にならないもの。 結果や件数の行へフォーカスを移せば読み上げられますが、カーソルが検索欄から抜け、検索を絞り直すには戻る場所を探す必要があります。リストに aria-busy を付けても、何も読み上げられません。入力中に検索欄の下に出る候補は、コンボボックスという別のパターンで、別の決まりがあります。
AI コーディングアシスタントで修正しますか? このガイドを Markdown で取得
修正の確認
マウスを使わない4つの確認
確認方法: スクリーンリーダー、キーボード
OS、ブラウザーと支援技術のバージョン、ビルド、実施日、各手順の実際の結果を記録してください。検索のコンポーネント、結果のテンプレート、ページのレイアウトを変更した際は、再度確認します。
制限
ライブリージョンの動きは、スクリーンリーダーやブラウザーによって異なります。入力を続けていると、控えめなメッセージを読まずに捨てるものもあります。このパターンは、一つのページの一つの検索欄を扱っています。下書きの保存のメッセージは画面に出ても読み上げられないステータスメッセージで扱っています。無限スクロールや「もっと見る」は、読み込みの別のトピックです。実際の絞り込み、並べ替え、ページ送りを含めた実際の検索を、利用者が使うスクリーンリーダーで確認してください。
よくある問題を再現した学習用のサンプルです。実在のクライアントの診断結果ではありません。コードは出発点となる実装例のため、実際の製品でも確認してください。ここでは支援技術でのテスト結果は報告していません。
コードを更新しても、使いやすさを保つために
ガイドの内容を、コーディングエージェントやCIで使える開発ルールにまとめます。更新後は、キーボードとスクリーンリーダーで再テストし、問題が再発していないか確認します。