トピックを検索
カードを移動しても何も読み上げないタスクボード
カードはボタンでもドラッグでも別の列へ移動できますが、新しい位置は列と件数として画面に出るだけで、移動先を伝えるライブリージョンがありません。
list.append(card); 問題
スクリーンリーダーの利用者は、カードを移動しても移動先について何も聞こえないため、カードを離れて列を読みに行かない限り、移動できたか分かりません。
チームのタスクボードに「未着手」「作業中」「完了」の3列があり、各見出しの横にカードの枚数が出ています。ボードはドラッグしなくても使えるように作られていて、各カードには移動先の列ごとにボタンがあります。ドラッグで動かしたい人向けに、ドラッグもそのまま使えます。「リリースノートを書く」の「完了へ移動」を押すと、カードは「完了」へ移り、「未着手」の件数は2から1に、「完了」は0から1になり、フォーカスは移動先のカードの最初のボタンに移ります。画面を見ている人には、カードが移ったことがすぐ分かります。スクリーンリーダーの利用者に聞こえるのは「未着手へ移動、ボタン、リリースノートを書く」で、フォーカスが移ったボタンの名前です。カードが今「完了」にあることも、移動できたことも伝わりません。手がかりは、カードのボタンが別の列を示すようになったことだけで、そこから自分で推測するしかありません。確かめるには、カードを離れ、「完了」の見出しを探して列を読み、元の場所へ戻ります。ボードは作業の状態を変える場所なので、これが1日に何度も起きます。
「『リリースノートを書く』を完了へ移動しました」は、ステータスメッセージです。利用者が行った操作の結果を伝え、フォーカスを受け取りません。画面では、その結果が2か所に出ています。新しい列にあるカードと、見出しの件数です。達成基準4.1.3では、こうしたメッセージを、ロールやプロパティによって支援技術に伝えられるようにし、フォーカスを移さなくても読み上げられることを求めています。ここでは件数がライブリージョンになく、カードの移動先を伝えるものもほかにないため、失敗例F103にあたります。フォーカスをカードに移しても、その代わりにはなりません。フォーカスが移るボタンの名前は「未着手へ移動」のままで、カードの題名はその説明として読まれるため、スクリーンリーダーが伝えるのは、起きたことではなく、ボタンを押せば次に何が起きるかです。ブラウザーから伝わる情報も、ほかにはありません。DOMの中で要素を移動しても、支援技術がすでに監視している領域にページが言葉を書き込まない限り、何も読み上げられません。
ボードは、全体を一目で見られる人には使えます。カードの新しい位置が、そのまま確認になるからです。カードが多いボードや、狭い画面で1列に並んだボードでは、一目で見渡せない人にとって、その位置を探すのが難しくなります。
10グループ中1グループに影響
- 全盲 (影響あり)
- 弱視 (影響なし)
- 色覚 (影響なし)
- ろう (影響なし)
- 難聴 (影響なし)
- 発話 (影響なし)
- 手の操作 (影響なし)
- 届く範囲・力 (影響なし)
- 認知 (影響なし)
- 光過敏 (影響なし)
- 視覚を使わない スクリーンリーダーの利用者が「完了へ移動」を押すと、聞こえるのはフォーカスが移ったボタンで、カードの移動先ではありません。確かめるには、移動のたびにカードを離れ、「完了」の見出しを探して列を読む必要があります。
自動チェックが見るのは、名前のあるボタン、見出しのある列、カードのリストで、どれも正しいマークアップです。「完了へ移動」を押さないので、カードが動くところを見ることはなく、件数が結果を伝えていることもマークアップからは分かりません。EaseWebの診断は、ドラッグできる項目のリストで、どの項目もドラッグせずに移動できるのに、ページにライブリージョンがない場合や、リストがライブリージョンの中にある場合に、手作業で確かめる項目として報告します。移動を読み上げるようにとAIに頼むと、ボード全体や各列に aria-live="polite" を付けることがよくあります。するとスクリーンリーダーが読むのは、加わったテキストです。移動したカードの題名とボタン、それに変わった2つの件数の数字だけで、どの列かを示す言葉はありません。aria-atomic="true" も付けると、移動のたびに、変わった領域を丸ごと読みます。ボード全体か2つの列の、すべてのカードです。何が読まれるかは、スクリーンリーダーを動かしてカードを移動しないと分かりません。
試してみる
「リリースノートを書く」の「完了へ移動」を押して、読み上げを聞いてください。次に、カードを別の列へドラッグしてください。
スクリーンリーダーが読み上げる内容が下の欄に表示されます。移動のたびに、カードの移動先は伝わりますか?
問題あり 修正できますか?
未着手 2
- リリースノートを書く
- 料金ページを更新する
作業中 1
完了 0
スクリーンリーダーの読み上げ:
(移動ボタンを押すか、カードをドラッグしてください)
修正方法
移動の前からページにあるステータス領域に、カードの移動先を書き込みます。
- 1ステータス領域は最初から1つ、ボードの外に置く。
- 2どの方法で移動しても、カードと移動先の列を1回伝える。
- 3ボード、列、カードのリストをライブリージョンにしない。
<section class="column" data-column="todo"> <h2>未着手 <span class="count">2</span></h2> <ul> <li data-card="notes" draggable="true"> <span id="card-notes">リリースノートを書く</span> <button type="button" data-to="doing" aria-describedby="card-notes">作業中へ移動</button> <button type="button" data-to="done" aria-describedby="card-notes">完了へ移動</button> </li> … </ul></section><!-- 作業中と完了も同じ:件数付きの見出しとカードのリスト -->ボードの下に移動を伝える行
<section class="column" data-column="todo"> <h2>未着手 <span class="count">2</span></h2> <ul> <li data-card="notes" draggable="true"> <span id="card-notes">リリースノートを書く</span> <button type="button" data-to="doing" aria-describedby="card-notes">作業中へ移動</button> <button type="button" data-to="done" aria-describedby="card-notes">完了へ移動</button> </li> … </ul></section><!-- 作業中と完了も同じ:件数付きの見出しとカードのリスト --><p id="board-status" role="status" class="board-status"></p>カードは移動し、件数は変わり、フォーカスもカードについていきますが、どれもライブリージョンにないため、スクリーンリーダーが読めるのはフォーカスのあるボタンだけです。
role="status" の p は最初からHTMLにあり、空で、列の外にあります。そのため、最初の移動で書き込む時点で、ブラウザーはすでにこの要素を監視しています。「完了へ移動」を押すと、スクリーンリーダーは新しくフォーカスしたボタンを読み、続けて「『リリースノートを書く』を完了へ移動しました。」と読みます。文には画面と同じ言葉でカード名と列名が入り、ボードのほかの部分は読まれません。ドラッグのドロップも同じ関数を呼ぶので、マウスで動かしても同じ言葉で読み上げられます。この行は、見える人にも直前の移動を示し、長いボードでカードが画面の外へ移ったときの助けにもなります。
どちらも、フォーカスを移さずにすべての移動を読み上げ、コードも同じです。ボードの下の行は、見える人にも直前に起きたことを伝え、後から加える「元に戻す」やエラーを出す場所にもなります。デザインに場所があるなら、こちらを選んでください。隠した領域ならボードの見た目は変わらないので、変更できないデザインやテーマにも使えます。各メッセージに項目名と移動先が入っていれば、1つの領域でサイト中のボードとリストをまかなえます。
どの移動方法でも、同じメッセージ。 文は、カードを動かす1つの関数で書き込み、移動ボタン、「移動先」のリスト、キーボードドラッグ、マウスのドロップのどこからもその関数を呼びます。ボタンでの移動は読まれるのにドロップは黙っているボードでは、ドラッグするスクリーンリーダーの利用者や、読み上げ付きの画面拡大ソフトを使う人が取り残されます。
何を伝えるか。 カード名と移動先の列名を、画面と同じ言葉で伝えます。たとえば「『リリースノートを書く』を完了へ移動しました。」です。位置は、移動で位置を選んだときや、列が決まった順に並んでいるときだけ加えます(「完了の3件中2番目に移動しました」)。ボードの新しい状態、件数、カードの詳細は読み上げません。知りたい人は列を読めます。サーバーが移動を受け付けないときや、列の枚数の上限で移動できないときも、言葉で伝えます。「『リリースノートを書く』を移動できませんでした。未着手のままです。」
フォーカスが先、メッセージは後。 フォーカスをカードに移してから、文を書き込みます。politeのメッセージは、新しくフォーカスしたボタンをスクリーンリーダーが読み終えるまで待つことになっています。フォーカスを移す前に書き込むと、新しいフォーカスの読み上げに途中で切られることがあります。移動後にフォーカスを置く場所は、「マウスでしか動かせないドラッグ&ドロップのボード」で説明しています。
ドラッグの途中は伝えない。 マウスでカードを動かしている間は何も伝えず、置いた先を伝えます。キーボードドラッグは別です。スクリーンリーダーの利用者にはカードの位置が見えないため、「持ち上げました」「作業中の列の上です」「完了に置きました」「未着手に戻しました」と、段階ごとにその場で伝えます。ドラッグ&ドロップのガイドのキーボードドラッグも、この形です。
修正にならないもの:ボードをライブリージョンにする。 ボード、列、リストに aria-live や role="status" を付けると、スクリーンリーダーは変化の意味ではなく、変わった内容を読みます。aria-atomic がなければ、加わったカードの題名とボタン、それに件数の数字だけです。あれば、移動のたびに領域全体を読みます。ボード全体か2つの列にある、すべてのカードです。メッセージは読み上げに埋もれるか、そもそも含まれません。
領域は先に置く。 領域はページに1回だけ、移動で描き直される列のコンポーネント、キー付きのリスト、{#if} の外に置きます。メッセージと一緒に現れた領域は、たいてい読み上げられません。この失敗は「画面に出ても読み上げられないステータスメッセージ」で詳しく扱っています。
ドラッグのライブラリー。 ドラッグ&ドロップのライブラリーには、独自のライブリージョンを持ち、標準でドラッグを読み上げるものがあります。使われる言葉を確認してください。たとえばdnd-kitの標準のメッセージは、項目とドロップ先をIDで呼ぶため、カードの題名と列の名前を使うメッセージを渡します。1回の移動に使うのは、ライブラリーの領域か自分の領域のどちらか一方にしてください。両方を使うと、移動のたびに2回読まれます。
緊急度。 role="status" はスクリーンリーダーが読み終えるのを待つため、移動に向いています。role="alert" や aria-live="assertive" は使わないでください。新しいフォーカスの読み上げを遮ることがあります。
AI コーディングアシスタントで修正しますか? このガイドを Markdown で取得、または全ガイドをコーディングエージェントで使う。
修正の確認
4つの確認
確認方法: スクリーンリーダー、キーボード、マウス
OS、ブラウザーと支援技術のバージョン、ビルド、実施日、各手順の実際の結果を記録してください。ボードのコンポーネントやドラッグのライブラリーを変更した際は、再度確認します。
制限
ライブリージョンの動きはスクリーンリーダーやブラウザーによって異なり、とくに差が大きいのは、フォーカスの移動と重なったときのタイミングです。このパターンは、1つのボードで列の間をカードが移動する場合を扱います。ドラッグせずにカードを動かせるようにすることは「マウスでしか動かせないドラッグ&ドロップのボード」で、1つのリストの中で並べ替え、新しい位置を伝えることは「ドラッグでしか動かせないか、動かしても何も伝えない並べ替えリスト」で扱っています。ステータスメッセージ全般は「画面に出ても読み上げられないステータスメッセージ」で扱っています。ドラッグのライブラリー、列の枚数の上限、狭い画面のレイアウトを含め、実際のボードを、利用者が使うスクリーンリーダーで確認してください。
よくある問題を再現した学習用のサンプルです。実在のクライアントの診断結果ではありません。コードは出発点となる実装例のため、実際の製品でも確認してください。ここでは支援技術でのテスト結果は報告していません。
コードを更新しても、使いやすさを保つために
ガイドの内容を、コーディングエージェントやCIで使える開発ルールにまとめます。更新後は、キーボードとスクリーンリーダーで再テストし、問題が再発していないか確認します。