トピックを検索
ドラッグでしか動かせないか、動かしても何も伝えない並べ替えリスト
順位を付けるリストが、行のつまみをドラッグしないと並べ替えられません。または、「上へ移動」「下へ移動」のボタンで行は動いても、どこへ移ったかを何も伝えません。
<li draggable="true"> 問題
ドラッグできない人は順番をまったく変えられず、ボタンで行を動かすスクリーンリーダーの利用者は、どこへ移ったか分かりません。
注文の後、ショップが1つだけ質問をします。「注文するときに大切なものを、順位の高い順に並べてください。」「価格」「配送の速さ」「返品のしやすさ」「レビュー」の4行があり、どの行も、6つの点が並んだつまみで始まります。マウスなら「配送の速さ」を押し、「価格」の上まで運んで離すと、左の番号もそれに合わせて変わります。Tabキーを押すと、フォーカスはリストを素通りして「送信」ボタンへ移ります。行はTabの順序になく、つまみは絵で、操作要素ではありません。スマートフォンでは、行に指を置いて動かすと、行が運ばれずにページがスクロールすることがあります。ドラッグできない人は、ショップが書いた順番のまま送るしかなく、回答としては意味がありません。
ショップの2つ目の実装では、各行に「上へ移動」「下へ移動」のボタンを加えています。今度はキーボードでもボタンに届き、「配送の速さ」の「上へ移動」を押すと、行は先頭へ移ります。見える人には、行が動いたことが分かります。スクリーンリーダーの利用者に聞こえるのは、押す前と同じ「上へ移動、ボタン、配送の速さ」です。フォーカスが同じボタンに戻されたからです。項目が今1番目にあることも、そもそも動いたことも伝わりません。確かめるには、ボタンを離れてリストを先頭から読み、また戻ってきます。
1つ目の実装では、順番を変える方法がドラッグしかなく、押したままポインターを動かす必要があります。達成基準2.5.7では、ドラッグが本質的でない限り、クリックやタップだけで同じことができる方法を求めています。4つの言葉を並べるのに、ドラッグは本質的ではありません。その方法がないため、失敗例F108にあたります。行はリスト項目で、飾りのつまみがあるだけです。フォーカスできるものがないため、キーボードでも並べ替えられず、2.1.1も満たしません。つまみは持ち手に見えるだけで、絵は押せません。
2つ目の実装はこの2つの基準を満たしますが、問題はボタンを押した後にあります。画面では、押すと行の横の番号が変わります。「配送の速さ」は2から1に、「価格」は1から2になります。この番号は、フォーカスを受け取らずに操作の結果を伝えるもので、達成基準4.1.3についてのW3C自身の例にあるカートの件数と同じです。4.1.3では、こうしたメッセージを、ロールやプロパティによって、フォーカスを移さなくても支援技術に伝えられるようにすることを求めています。このガイドでは、番号がどれもライブリージョンにないことを失敗例F103と読んでいます。言葉のメッセージがページに加わる場合に限って4.1.3を当てはめる評価者もいますが、どちらにしても観察できることは同じです。フォーカスが戻るボタンは名前も説明も変わらないため、スクリーンリーダーには新しく伝えることがなく、行がどこへ移ったかを伝えるものもページにはありません。DOMの中で要素を動かしても何も読まれず、中のボタンからはフォーカスが外れます。スクリプトがフォーカスを戻しているのはそのためです。
このリストに答えられるのは、全体を一目で見られ、楽にドラッグできる人です。それ以外の人は、順番を変えられないか、今どんな順番か分かりません。並びの変わっていない回答は、結果を読む人には本当の回答に見えます。
10グループ中3グループに影響
- 全盲 (影響あり)
- 弱視 (影響なし)
- 色覚 (影響なし)
- ろう (影響なし)
- 難聴 (影響なし)
- 発話 (影響なし)
- 手の操作 (影響あり)
- 届く範囲・力 (影響あり)
- 認知 (影響なし)
- 光過敏 (影響なし)
- 手の操作が限られる キーボード、スイッチ、音声操作の利用者は、押したまま動かせません。つまみにはTabも届かないため、ドラッグでしか動かないリストでは順番をまったく変えられず、回答は最初の並びのまま送られます。
- 視覚を使わない スクリーンリーダーの利用者には、ドラッグした行がどこに入るかが見えません。「上へ移動」「下へ移動」があっても、押すと同じボタンがまた読まれるだけで、項目がどこへ移ったかは聞こえないため、押すたびにリスト全体を読んで探します。
- 届く範囲・力が限られる 手のふるえや握力の弱さがある人は、1行早く、または1行遅く指を離してしまい、1回の移動のために何度もドラッグし直すこともあります。
マークアップには誤りがありません。リスト項目に名前は不要で、draggable="true" も正しいHTMLで、移動ボタンにも名前があります。自動チェックは行をドラッグすることもボタンを押すこともないため、順番を変えられないことにも、変えても何も読まれないことにも気付きません。EaseWebの診断は、ドラッグできる項目が並ぶリストで、項目に自前のボタンやselectがないものを、手作業で確認する項目として報告します。また、どの項目もドラッグせずに動かせても、リストの外にライブリージョンがない場合や、リストがライブリージョンの中にある場合は、もう1つの確認項目として報告します。リストのアクセシビリティ改善をAIに頼むと、つまみに tabindex="0" と role="button" を付けることがよくあります。Tabの順序には入りますが、キーボードでできることは何もありません。リストに aria-live を付けることもありますが、動いた行のテキストとボタンがもう一度読まれるだけで、位置は伝わりません。
試してみる
「配送の速さ」を先頭にしてください。ドラッグしてから、マウスを使わずにTabで試してください。
スクリーンリーダーが読み上げる内容が下の欄に表示されます。問題1では、ドラッグせずに行を動かせますか?問題2では「上へ移動」を押してください。行の移動先は伝わりますか?
問題あり 修正できますか?
注文するときに大切なものの順位
- 価格
- 配送の速さ
- 返品のしやすさ
- レビュー
スクリーンリーダーの読み上げ:
(Tabで行へ移動するか、ドラッグしてください)
修正方法
ドラッグは残し、押すだけで各行を動かせる操作要素を加え、行の新しい位置をステータス領域で伝えます。
- 1ドラッグせず、クリック、タップ、キー操作1回ずつで、どの行も上下に動かせる。
- 2移動のたびに、項目と新しい位置を、フォーカスを動かさずに1回伝える。
- 3ドラッグは近道として残し、順番を変える唯一の方法にはしない。
ドラッグでしか動かない行
<h2 id="rank-title">注文するときに大切なものの順位</h2><ol id="ranking" aria-labelledby="rank-title"> <li draggable="true" data-item="speed"> <svg class="grip" aria-hidden="true">…</svg> <span id="item-speed">配送の速さ</span> </li> …</ol>移動のたびに伝える「上へ移動」「下へ移動」
<h2 id="rank-title">注文するときに大切なものの順位</h2><ol id="ranking" aria-labelledby="rank-title"> <li draggable="true" data-item="speed"> <svg class="grip" aria-hidden="true">…</svg> <span id="item-speed">配送の速さ</span> <button type="button" data-move="-1" aria-describedby="item-speed">上へ移動</button> <button type="button" data-move="1" aria-describedby="item-speed">下へ移動</button> </li> …</ol><p id="rank-status" role="status"></p>この方法を選ぶ理由:ジェスチャーは近道にし、唯一の方法にしない
行を動かす方法はドラッグだけです。つまみは支援技術から隠され、フォーカスもできず、リスト項目は押せません。
どのボタンも、1回のクリック、タップ、キー操作で行を1段動かすので、ドラッグは要らなくなり、音声操作では「上へ移動をクリック」と言えます。項目の名前は各ボタンの説明として読まれるため、表示テキストを変えずに、どの行を動かすボタンか伝わります。移動後、フォーカスはボタンに戻り、最初からページにあるステータス領域が「配送の速さを4件中1番目に移動しました。」と伝えます。ドラッグして離したときも同じ関数を呼ぶので、マウスで動かしても同じ言葉で読まれます。もう一度「上へ移動」を押しても、ボタンはフォーカスの下から消えずにその場に残り、ステータス領域が「配送の速さはすでに先頭です。」と伝えます。この方法は短いリスト向きです。6件中6番目の項目を先頭へ動かすには、5回押す必要があります。
「上へ移動」「下へ移動」と「順位」のリストは、どちらも単独で基準を満たし、キーボード、ポインター、スクリーンリーダーのどの利用者にも使えます。ボタンは1段動かすごとに1回押す方法で、見つけやすく、音声でも言いやすいため、5〜6件までの短いリストに向いています。「順位」のリストは、どの移動も2段階で、リストが長くなっても変わりません。長いリストや、項目が何段も動くことが多いときは、こちらを選んでください。キーボードドラッグは、キーボード利用者がもっと速い方法を求めるときに加える価値がありますが、必ずほかの方法と組み合わせてください。
ドラッグは残してください。ドラッグできる人にとっては速い方法です。2.5.7が求めているのはドラッグ以外の方法を加えることで、ドラッグをなくすことではありません。ドラッグは行に、操作要素はその中に置き、ボタンを押してもドラッグが始まらないようにします。ボタンの処理は押し下げた時点ではなくクリックで実行し、押し間違いを取り消せるようにします。
移動後のフォーカス。 DOMの中で要素を動かすと、その中の操作要素からフォーカスが外れるため、スクリプトでフォーカスを戻します。フレームワークがリストを更新すると、行は移動されるか新しく作られ、どちらの場合も操作要素からフォーカスが外れます。リストが更新された後で、その行の操作要素にフォーカスを移してください。項目が先頭まで来たときの「上へ移動」のように、フォーカスのあるボタンを無効化したり、隠したり、取り除いたりしないでください。Chromeではフォーカスがページ全体に移ってしまい、利用者はリストのどこにいたかを見失います。ボタンは残して「配送の速さはすでに先頭です。」と伝えます。デザインで薄く表示するなら、aria-disabled="true" を付けると、使えないことが読まれ、Tabの順序にも残ります。
メッセージで伝えること。 項目の名前と新しい位置を、リストに表示している番号で伝えます(例:「配送の速さを4件中1番目に移動しました。」)。フォーカスを戻した後で書き込むと、スクリーンリーダーはボタンを読んでからメッセージを読みます。role="alert" ではなく、読み終えるのを待つ role="status" を使います。新しい並び全体を読ませないでください。リスト自体をライブリージョンにするのも避けてください。リストをライブリージョンにすると、動いた行のテキストとボタンがもう一度読まれ、aria-atomic="true" ならすべての行が読まれますが、項目がどこへ移ったかは伝わりません。
グリッドと長いリスト。 折り返す写真のグリッドでは、上下は前後の意味になるため、ボタンは「前へ移動」「後ろへ移動」にするか、「順位」のリストを用意します。長いリストでは、「先頭へ移動」「末尾へ移動」のボタンがあると、押す回数を大きく減らせます。
並びの保存。 移動のたびにすぐ保存する場合は、サーバーが受け付けなかった移動も、項目を元に戻したうえで伝えます。「配送の速さを移動できませんでした。4件中2番目のままです。」フォームで並びを送る場合は、送信する欄を行と同じ順番に保ちます。
ドラッグのライブラリー。 並べ替えのライブラリーの多くは、キーボードドラッグと独自のライブリージョンを持っています。読み上げる言葉は、項目をIDで呼んでいることがあるので確認してください。そのうえで、2.5.7のためにボタンか「順位」のリストを加えます。1回の移動に使うのは、ライブラリーの領域か自分の領域のどちらか一方にしてください。両方を使うと、移動のたびに2回読まれます。
1つのリストの中ではなく、リストや列の間で項目を動かすことは「マウスでしか動かせないドラッグ&ドロップのボード」で、その移動を読み上げることは「カードを移動しても何も読み上げないタスクボード」で扱っています。
AI コーディングアシスタントで修正しますか? このガイドを Markdown で取得、または全ガイドをコーディングエージェントで使う。
デザインの案
順位のリストは、すっきりしたままでもドラッグなしで動かせます。
同じ順位の質問を6通りに描きました。クリックで試してから、マウスを使わずにTabでも試してください。4つは1回ずつ押すだけで行が動き、移動先を伝えます。2つは、ポインターを押さえたままでないと動きません。
デザインファイルで
- どの行の移動用の操作も、ホバーや長押しの後だけでなく、何もしていない状態で描く。
- 移動を知らせる1行をリストの下に描く。たとえば「配送の速さを3件中1番目に移動しました。」
- リストの両端を描く。先頭の行の「上へ移動」は薄くしても残し、押したときに伝える言葉も書く。
- 移動用の操作それぞれにフォーカスの枠を付け、開くメニューや番号も描く。
- スマートフォンのレイアウトでも移動用の操作をすべて表示し、どれも最小24 × 24ピクセルで描く。
合格
- 移動メニューを開くつまみ 6つの点のつまみはデザインどおりの位置にありますが、32pxのボタンです。クリック、タップ、Enterで「先頭へ」「上へ」「下へ」「末尾へ」のメニューが開き、ドラッグもこれまでどおり使えます。何もしていないときの見た目は描いたとおりです。デザインファイルには、つまみのフォーカスの枠と、開いたメニューを描きます。
- 価格
- 配送の速さ
- 返品のしやすさ
押して変える順位の番号 各行の先頭の番号が、直径28pxの丸いボタンです。押すと横に1〜3の番号が並び、どの行も2回押すだけで好きな順位へ移せます。番号そのものが答えになる順位の質問に向いていて、行の右端には何も増えません。- 大切な順にタップ 並べ替えるリスト自体がありません。大切な順に選択肢をタップすると、それぞれに番号のバッジが付き、もう一度タップすると外れます。どの操作も、高さ44pxのボタンを1回押すだけで、スマートフォンでも同じように使えます。選択肢の下の1行が、付いた順位を伝えます。
- 価格
- 配送の速さ
- 返品のしやすさ
各行に小さな上下の矢印 各行の右端に、28 × 28ピクセルの山形の矢印を上下に重ねます。言葉のボタンより控えめです。表示する言葉がないので、名前は「上へ移動:配送の速さ」のように操作から始め、音声操作でもそのまま言えるようにします。先頭の行の上矢印は薄くしても残し、押すと、すでに先頭であることを伝えます。
不合格
- 価格
- 配送の速さ
- 返品のしやすさ
ホバーで現れるつまみWCAG 2.5.7 最もすっきりしたリストです。行にポインターを重ねたときだけつまみが現れ、行を動かす方法はそれをドラッグすることだけです。Tabで押せるものはなく、スマートフォンではつまみが表示されません。「移動メニューを開くつまみ」のように、メニューを開くボタンとして描きます。- 価格
- 配送の速さ
- 返品のしやすさ
長押しで持ち上げるWCAG 2.5.7 スマートフォンのアプリでおなじみの形です。行を0.5秒押さえて持ち上がったら、そのままドラッグして置きます。動かす方法は長押しとドラッグだけなので、キーボード、スイッチ、音声操作の利用者は動かせず、そもそも動かせることを示すものが行にありません。
修正の確認
5つの確認
確認方法: キーボード、マウス、タッチ、スクリーンリーダー
OS、ブラウザーと支援技術のバージョン、ビルド、実施日、各手順の実際の結果を記録してください。リストのコンポーネントやドラッグのライブラリーを変更した際は、再度確認します。
制限
このサンプルは、どのアプリケーションでも同じ結果になることを保証するものではありません。入れ子のリスト、項目の階層を変えられるツリー、スクロールすると項目が増えるリストには、それぞれ別の配慮が必要で、ここでは扱いません。並べ替えのライブラリーによって、フォーカス、キー、読み上げの扱いは異なります。利用者が使う支援技術で、操作全体を確認してください。
よくある問題を再現した学習用のサンプルです。実在のクライアントの診断結果ではありません。コードは出発点となる実装例のため、実際の製品でも確認してください。ここでは支援技術でのテスト結果は報告していません。
コードを更新しても、使いやすさを保つために
ガイドの内容を、コーディングエージェントやCIで使える開発ルールにまとめます。更新後は、キーボードとスクリーンリーダーで再テストし、問題が再発していないか確認します。