トピックを検索
右クリックや長押し、スワイプでしか出ない操作メニュー
一覧の操作が、右クリックや長押しでしか開かないメニューか、スワイプの奥にしかなく、行にはそこへ届くボタンがありません。
list.addEventListener('contextmenu', openMenu) 問題
キーボード、スイッチ、音声操作、スクリーンリーダーの利用者と、ジェスチャーに気付かない人は、行の操作に届きません。
顧客向けのポータルに、共有された書類の一覧があります。ファイルを右クリックすると、ブラウザーのメニューの代わりに、サイト独自のメニューがポインターの位置に開きます。「ダウンロード」「コピーを作成」「削除」です。スマートフォンでは、行を長押しすると同じメニューが開きます。狭い画面のレイアウトには、もう一つジェスチャーがあります。行を左へスワイプすると、下から「削除」ボタンが出てきます。Tabキーを押すと、フォーカスは一覧を素通りして、その下にあるヘルプのリンクへ飛びます。行はフォーカスを受けず、メニューのボタンはメニューが開いている間しか存在しません。
操作には、それ自体の操作要素がありません。右クリック、0.5秒の長押し、スワイプという、ポインターのイベントからしか実行できません。WCAG 2.1.1は、すべての機能をキーボードで使えることを求めています。失敗例F54は、まさにこのパターン、つまりポインター固有のイベントハンドラーだけで機能を実行することを挙げています。スワイプは2.5.1も満たしません。ポインターがほぼまっすぐ左へ動いたときだけ認識される、経路に基づくジェスチャーです。2.5.1は、ボタンのタップのように、経路のない1本のポインターで同じことができる方法を求めています。右クリックと長押しは1本のポインターの操作なので、それ自体は2.5.1に反しません。問題は、ほかに操作へ届く方法がないことです。
ファイルの一覧、メッセージのスレッド、保存した商品の一覧では、ダウンロード、名前の変更、削除が右クリックメニューにしかないことがよくあります。スマートフォンのレイアウトでは、場所を空けるために行のボタンが省かれ、スワイプしか残らないこともあります。同じ一覧が、パソコンでは使えても、スマートフォンでは人を締め出します。
10グループ中4グループに影響
- 全盲 (影響あり)
- 弱視 (影響なし)
- 色覚 (影響なし)
- ろう (影響なし)
- 難聴 (影響なし)
- 発話 (影響なし)
- 手の操作 (影響あり)
- 届く範囲・力 (影響あり)
- 認知 (影響あり)
- 光過敏 (影響なし)
- 手の操作が限られる キーボード、スイッチ、音声操作の利用者には、押す右ボタンも、押したまま待つ操作も、スワイプもありません。行はTabの順序にもないため、どの操作にも届きません。
- 視覚を使わない スクリーンリーダーの利用者には、各行がただのテキストとして読まれ、操作があることを示すものが何もありません。ダウンロードや削除ができることを知る機会がありません。
- 届く範囲・力が限られる 手のふるえや握力の弱さがある人は、長押しがスクロールに、スワイプがタップに変わってしまい、操作が表示されません。
- 言語・認知・学習の能力が限られる 右クリック、長押し、スワイプでほかの操作が出ることは、行のどこにも示されていません。ジェスチャーを知らない人は、操作を見つけられません。
自動チェックが読むマークアップには、誤りがありません。リスト項目に名前は不要で、メニューのボタンは本物のボタンです。contextmenu のリスナーは属性を何も残さず、スワイプもほかと同じポインターのリスナーです。ほかの方法で操作に届くかは、キーボードで試して初めて分かります。修正をAIに頼むと、Shift+F10でメニューが開くように、行に tabindex="0" と role="button" を付けることがよくあります。行にフォーカスは届きますが、メニューがあることは画面に示されず、「ボタン」なのにEnterでは何も起きません。Macではスクリーンリーダーを使わない限りメニューを開くキーがなく、タッチの利用者はやはりジェスチャーを知っている必要があります。
試してみる
「署名済み契約書.pdf」を削除してください。右クリックか長押し、「問題2」では左へのスワイプです。次に、マウスを使わずにTabで試してください。
下の欄に、スクリーンリーダーの読み上げが出ます。ジェスチャーを使わずに「ダウンロード」「コピーを作成」「削除」に届きますか?どのファイルに対する操作か聞こえますか?
問題あり 修正できますか?
スクリーンリーダーの読み上げ:
(Tabでファイルへ移動するか、右クリックしてください)
修正方法
ジェスチャーは近道として残し、すべての行に、同じ操作へ届くボタンを置きます。
- 1右クリック、長押し、スワイプのメニューにある操作は、どれも行のボタンか、行のボタンで開くメニューにもある。
- 2それらの操作にはキーボードで届き、どの行に対するものかを伝える。
- 3操作で行が消えたら、フォーカスはbodyではなく、次の行の操作要素へ移る。
右クリックか長押しでしか開かないメニュー
<ul class="files"> <li data-file="invoice">請求書 0412.pdf</li> <li data-file="contract">署名済み契約書.pdf</li> <li data-file="brand">ブランドガイド.pdf</li></ul><div class="file-menu" hidden> <button type="button" data-action="download">ダウンロード</button> <button type="button" data-action="copy">コピーを作成</button> <button type="button" data-action="delete">削除</button></div>同じ操作を開く「操作」メニューボタン
<li data-file="invoice"> <span id="file-invoice">請求書 0412.pdf</span> <button type="button" popovertarget="menu-invoice" aria-haspopup="menu" aria-describedby="file-invoice"> 操作 </button> <div id="menu-invoice" popover role="menu" aria-labelledby="file-invoice" class="file-menu"> <button type="button" role="menuitem" tabindex="-1" data-action="download">ダウンロード</button> <button type="button" role="menuitem" tabindex="-1" data-action="copy">コピーを作成</button> <button type="button" role="menuitem" tabindex="-1" data-action="delete">削除</button> </div></li>この方法を選ぶ理由:ジェスチャーは近道にし、唯一の方法にしない
メニューは、右クリックか、押したままのタッチでしか開きません。行はフォーカスを受けないため、キーボード利用者はShift+F10が効く場所にも行けず、メニューがあることも画面には示されません。
すべての行に、クリック、タップ、Enter、Spaceでメニューを開くボタンが表示されます。音声操作では「操作をクリック」と言えます。メニューは、利用者がまず試すブラウザー自身のコンテキストメニューと同じように動きます。フォーカスは最初の操作に移り、上下の矢印キーで操作の間を移動し、HomeとEndで最初と最後へ、Enterで実行し、Tabでメニューを閉じて先へ進みます。残りは popover 属性が担います。メニューはページの上に開き、Escapeか外側のクリックで閉じ、フォーカスは「操作」ボタンに戻ります。aria-haspopup="menu" で、ボタンがメニューを開くことがスクリーンリーダーに伝わります。メニューの名前はファイル名から取るため、フォーカスが入ると「請求書 0412.pdf、メニュー」と読まれます。右クリックと長押しのメニューはそのまま残せるため、近道もなくなりません。メニューは、CSSのアンカー位置指定か数行のスクリプトで、ボタンの下に置いてください。指定しないと、ポップオーバーは画面の中央に出ます。
どちらもそれだけで、キーボード、ポインター、タッチ、スクリーンリーダーの利用者に対応できます。行のボタンは1回押すだけで、すべての操作がひと目で分かりますが、操作が増えるたびに行が大きくなり、ボタンごとにTabで止まるため、行が多い一覧ではTabでの移動が長くなります。操作が2〜3個なら行のボタンを選んでください。「操作」ボタンは、操作がいくつあっても1行につきTabで止まるのは1回で、場所も取りませんが、2回押す必要があり、開くまで操作は見えません。操作が多いときや、狭いレイアウトでは「操作」ボタンを選んでください。よく使う操作だけを独立したボタンにし、残りを「操作」に入れる組み合わせもよく使われます。
ジェスチャーは残してください。右クリックやスワイプは、使う人にとっては速い方法で、達成基準が求めるのは別の方法であり、置き換えではありません。ブラウザーのメニューを止めるのは行の上だけにし、ページ全体では止めないでください。ブラウザーのメニューには、コピー、新しいタブで開く、翻訳、スペルの候補があり、頼りにしている人がいます。
行をフォーカスできるようにして、Shift+F10やアプリケーションキーで独自のメニューを開くのは、追加としては役立ちますが、修正にはなりません。これらのキーはWindowsとLinuxでは contextmenu を出しますが、Macにはそのキーがなく、試せることも画面に示されず、タッチの利用者は何も変わりません。
メニューの種類によって、細かい点が変わります。
- ポップオーバーに普通のボタン:メニューのロールを付けず、Tabで届く普通のボタンを並べたポップオーバーも達成基準を満たし、コードも少なくて済む。ただし、コンテキストメニューに見えるものを開いた人は、まず矢印キーを試す。普通のボタンのままにするなら、メニューだと伝えないよう、
aria-haspopup="menu"とメニューのロールは付けない。 - コンポーネントライブラリー:
role="menu"を付けるメニューのコンポーネントは、フォーカスをメニューの中へ移し、矢印キーで項目の間を動けるようにする必要もある。頼る前に、そうなっているか確認する。 - アイコンのボタン:「⋯」で描く「操作」ボタンには、アクセシブルな名前が必要になる。詳しくは名前がないアイコンだけのボタンを参照。名前には「その他の操作」のように、人が口にする言葉を使う。
- 開閉の状態:ブラウザーは
popovertargetのボタンを展開・折りたたみとして伝えるため、aria-expandedは不要。対象とするスクリーンリーダーで確認する。 - メニューのスタイル:ポップオーバーに
display: gridやflexのクラスのようなdisplayを指定すると、ブラウザーの非表示のルールより優先され、閉じていてもメニューが見えてしまう。displayは:popover-openの中で指定する。 - 指についてくるスワイプ:押している間、行がポインターと一緒に動くものはスワイプではなくドラッグで、2.5.7も関わる。同じボタンで修正できる。マウスでしか動かせないドラッグ&ドロップのボードを参照。
- 選択:各行にチェックボックスを置き、一覧の上のツールバーでチェックした行に操作する方法も、達成基準を満たす。複数の行にまとめて操作する一覧に向くが、変更は大きく、ツールバー自体のパターンも必要になる。
操作で行が消えるときは、フォーカスに注意が必要です。フォーカスがその行の「削除」やメニューの中にあった場合は、次の行の同じ操作要素へ移します。最後の行なら前の行へ、一覧が空になったら一覧の見出しへ移します。そうしないとフォーカスはbodyに落ち、キーボード利用者はページの先頭からやり直しになります。
AI コーディングアシスタントで修正しますか? このガイドを Markdown で取得
修正の確認
5つの確認
確認方法: キーボード、マウス、タッチ、スクリーンリーダー、音声入力
OS、ブラウザーと支援技術のバージョン、ビルド、実施日、各手順の実際の結果を記録してください。一覧のコンポーネントやメニューのライブラリーを変更した際は、再度確認します。
制限
このサンプルは、どのアプリケーションでも同じ結果になることを保証するものではありません。ドラッグで動かす行、長押しによる複数の項目の選択、ピンチでの拡大のような地図や画像のジェスチャーには、それぞれ別の配慮が必要で、ここでは扱いません。画像のジェスチャーについてはボタンで代われないピンチ・ドラッグ・傾きのジェスチャーを参照してください。メニューのライブラリーによって、フォーカス、Escape、配置の扱いは異なります。対象とする支援技術で、操作全体を確認してください。
よくある問題を再現した学習用のサンプルです。実在のクライアントの診断結果ではありません。コードは出発点となる実装例のため、実際の製品でも確認してください。ここでは支援技術でのテスト結果は報告していません。
コードを更新しても、使いやすさを保つために
ガイドの内容を、コーディングエージェントやCIで使える開発ルールにまとめます。更新後は、キーボードとスクリーンリーダーで再テストし、問題が再発していないか確認します。