トピックを検索
Tabで届くのに読み上げられない、aria-hiddenの要素
閉じたスライド式メニューを画面の外に移してaria-hidden="true"を付けているため、リンクはスクリーンリーダーから隠れても、すべてTabの移動先に残っています。
<nav class="drawer" aria-hidden="true"> 問題
キーボードやスクリーンリーダーの利用者が、見えず読み上げられないリンクにたどり着きます。
生活雑貨の店のサイトで、ヘッダーにメニューボタンがあります。押すと、左から「商品」「読みもの」「店について」「お問い合わせ」の4つのリンクを持つメニューが滑り出てきます。閉じている間、メニューは画面の左端のすぐ外で待機しています。メニューボタンからTabを押すと、フォーカス枠が消えます。さらに3回押しても見えません。5回目で、ようやくページ内の最初のリンクに戻ります。その4回分の移動先は、画面の外にある閉じたメニューのリンクでした。同じ4か所で、スクリーンリーダーは何も読み上げないことが多く、ブラウザーとの組み合わせによってはリンクの一部だけを読むため、同じページでも人によって聞こえる内容が違います。
閉じたメニューは transform で画面の外に移し、スクリーンリーダーが読み飛ばすよう aria-hidden="true" を付けています。aria-hidden の働きはそれだけで、メニューをアクセシビリティツリーから外します。Tabの移動先からは外さず、クリックも止めません。そのため、名前とロールが支援技術に伝わらないリンクにフォーカスが移り、4.1.2 名前・役割・値を満たしません。WAI-ARIAが、フォーカスを受ける要素への aria-hidden を禁じているのはこのためです。メニューは画面の外にあるため、その移動先ではフォーカス枠も見えず、存在しない操作要素を順に通ることになり、フォーカスの可視化とフォーカス順序の問題にもなります。ここで紹介する修正方法は、閉じている間リンクをTabの移動先から外すため、3つの問題をまとめて解決します。
同じ問題は、aria-hidden で隠した部分にフォーカスが届く場所すべてで起きます。画面の外にあるカルーセルのスライド、選ばれていないタブのパネル、独自ダイアログの背後のページ、商品カードで重複する写真のリンクなどです。マウス利用者は、画面の外のものをクリックできないため、この問題に出会いません。
10グループ中2グループに影響
axeの aria-hidden-focus は、ページを読み込んだ時点の状態でこの問題を見つけ、中にリンクを含む閉じたメニューを報告します。メニューの開閉は試さないため、操作の後で初めて aria-hidden が付く部分は見逃します。モーダルが開いているときや、フォーカス時の処理が付いているときは、失敗として報告せず確認を求めます。警告を消す手っ取り早い修正は aria-hidden の削除ですが、警告が消えても見えない4つの移動先は残り、今度は誰にも見えないリンクとして読み上げられます。今のテンプレートにあるリンクだけに tabindex="-1" を足す修正も、誰かがメニューにリンクを加えるまでしか持ちません。
試してみる
メニューボタンからTabキーを押し、フォーカスを追ってください。
メニューを閉じたまま、メニューボタンの次にフォーカスがどこへ行き、スクリーンリーダーが何を読むか見てください。次にメニューを開いて、Tabで中を移動してください。
問題あり 修正できますか?
スクリーンリーダーの読み上げ:
(Tabでメニューボタンへ移動)
再現デモです。「問題あり」は意図的にアクセシブルでない状態にしています。
修正方法
閉じたメニューは、CSSかinertで、画面、Tab、スクリーンリーダーから一度に隠します。
- 1フォーカスを受ける要素にも、それを含む要素にも、
aria-hidden="true"を付けない。 - 2使わない部分は全員から一度に隠す。CSSで隠すか
inertを付けるか、中の操作要素をすべてTabの移動先から外す。 - 3フォーカスがある部分を隠す前に、フォーカスを外へ移す。
<button type="button" class="menu-button" aria-expanded="false" aria-controls="menu">Menu</button><nav id="menu" class="drawer" aria-label="Main" aria-hidden="true"> <a href="/shop">Shop</a> <a href="/journal">Journal</a> <a href="/about">About</a> <a href="/contact">Contact</a></nav>CSSで隠した、閉じたメニュー
<button type="button" class="menu-button" aria-expanded="false" aria-controls="menu">Menu</button><nav id="menu" class="drawer" aria-label="Main"> <a href="/shop">Shop</a> <a href="/journal">Journal</a> <a href="/about">About</a> <a href="/contact">Contact</a></nav>この方法を選ぶ理由:隠すときは、全員から一度に隠す
transform は閉じたメニューを目から隠し、aria-hidden はスクリーンリーダーから隠しますが、キーボードからは何も隠していません。リンクはすべてTabの移動先に残り、画面の外で、スクリーンリーダーが読む名前も持たないままです。
visibility: hidden は、閉じたメニューを画面、キーボード、ポインター、スクリーンリーダーから一度に隠すため、aria-hidden は要らなくなります。visibility の遅延で、メニューが滑り出てから隠れ、開くときはすぐに表示されます。アニメーションがないメニューなら、hidden 属性(menu.hidden = !open)でも同じ結果になります。
どの方法も基準を満たします。閉じたメニューが完全に画面の外にある、よくある場合は、CSSで隠す方法がいちばん簡単です。ルールが一つで、どのブラウザーでも動き、スクリプトが忘れるものもありません。inert は、描画を残したまま同じ働きをするため、次のカルーセルのスライドの端や独自ダイアログの背後のページのように、使わない部分の一部を見せておく必要があるときに選びます。aria-hidden を残して操作要素ごとに tabindex="-1" を付ける方法は、既存のコンポーネントへの変更がいちばん小さい反面、操作要素ごとに付け、開閉のたびに戻す必要があるため、ほかの方法に移るまでの一時的な対応と考えてください。
フォーカスがある部分は、隠す前にフォーカスを移します。Escapeやメニュー内の閉じるボタンのように、フォーカスがメニュー内のリンクにある状態で閉じるとき、先にメニューを隠すと、フォーカスは誰も届かない要素に残り、ブラウザーはページの先頭に戻します。メニューボタンにフォーカスを移してから、メニューを隠してください。開くときは逆に、visibility: hidden や inert を外して表示してから、フォーカスを中に移します。
開いたメニューがページの一部を覆う場合も注意が必要です。Tabでメニューから下に隠れたリンクへ移れると、フォーカスは誰にも見えない場所に移ります。開いたメニューでページを横に押し出して後ろの要素を覆わないようにするか、モーダルにします。モーダルにする場合は、modal-focus-management のガイドのとおり、フォーカスを中に移し、ほかのページを inert にし、Escapeでメニューを閉じます。
同じ問題でも、隠しているものによって修正方法が変わります。
- 画面の外にあるカルーセルのスライド:表示していないスライドに
inertを付けるか、移動し終わってからvisibility: hiddenにする。マークアップを直す前に、カルーセルのライブラリーの設定を確認する。 - 選ばれていないタブのパネル:選ばれていないパネルに
hidden属性を付ける。 - 独自ダイアログの背後のページ:
modal-focus-managementのガイドのとおり、ページにinertを付ける。 - 商品カードで、タイトルのリンクと同じページを指す写真のリンク:ほかの操作要素を含まないため、そのリンクだけに
aria-hidden="true"とtabindex="-1"を付けてかまわない。写真とタイトルを一つのリンクにまとめる方法もある。
隠している部分が画面に表示され、使われるものなら、修正は逆です。aria-hidden を外して、全員に届くようにします。また、テンプレートだけでなく表示されたページを確認してください。外部スクリプトのメニュー、カルーセル、Cookieツールは、自分で aria-hidden を付けることがよくあります。
AI コーディングアシスタントで修正しますか? このガイドを Markdown で取得
修正の確認
マウスを使わない5つの確認
確認方法: キーボード、スクリーンリーダー
OS、ブラウザーと支援技術のバージョン、ビルド、実施日、各手順の実際の結果を記録してください。共通のメニュー、カルーセル、ダイアログのコンポーネントを変更した際は、再度確認します。
制限
このサンプルは、どのアプリケーションでも同じ結果になることを保証するものではありません。対象は、aria-hidden で隠してもフォーカスが届く部分です。フォーカスを受けないものの、価格や注意書きのように必要な情報を持つ要素に aria-hidden を付けるのは別の問題で、このガイドでは扱いません。隠れたリンクで何が読み上げられるかはブラウザーとスクリーンリーダーによって違うため、利用者が使う組み合わせで確認してください。
よくある問題を再現した学習用のサンプルです。実在のクライアントの診断結果ではありません。コードは出発点となる実装例のため、実際の製品でも確認してください。ここでは支援技術でのテスト結果は報告していません。
コードを更新しても、使いやすさを保つために
ガイドの内容を、コーディングエージェントやCIで使える開発ルールにまとめます。更新後は、キーボードとスクリーンリーダーで再テストし、問題が再発していないか確認します。