トピックを検索
フォーカス中のリンクを隠す固定ヘッダーとバナー
固定ヘッダーやCookieバナーの下のリンクを、ブラウザーは表示中とみなすため、バーの下から出すスクロールをしません。
問題
キーボード利用者が、ヘッダーやバナーの下に隠れたリンクにフォーカスし、それが見えません。
園芸サイト「ガーデンノート」に、「春の植え付けガイド」「コンポスト容器の選び方」「バラの剪定」などの記事リンクが並んでいます。ロゴとメニューのあるヘッダーは画面上部に固定され、下部には回答するまでCookieバナーが固定表示されます。Tabキーで一覧を進むと、次の二つのリンクはCookieバナーの下にあり、画面は動かないままフォーカスがそこへ移ります。誰にも見えないリンクにフォーカスがあります。Shift + Tabで戻ると、今度はヘッダーの下で同じことが起きます。
フォーカスが移ったとき、ブラウザーがスクロールするのは、要素がスクロール領域の外にある場合だけです。固定ヘッダーや固定バナーの下のリンクは領域の内側にあるため、ブラウザーは表示中とみなし、画面を動かしません。スクロールする場合も、その量はブラウザーによって異なります。要素を中央に移すものもあれば、端にそろえてバーの下で止めるものもあります。どちらの場合も、バーが画面の一部を覆っていることはブラウザーに伝わっていません。達成基準2.4.11は、フォーカスした要素が制作者の置いたコンテンツに完全に隠れないことを求めています。この例では、両方向で完全に隠れています。
キーボードで操作する晴眼の利用者は、現在位置が分からなくなり、見えていないリンクでEnterを押してしまうことがあります。スイッチ操作や音声操作でフォーカスを動かす人も同じです。拡大表示の利用者は特に影響を受けます。200%ではヘッダーとバナーが画面の3分の1を占め、より多くの部分がその下に入ります。
マークアップは正しく、リンク名も順序もフォーカス表示もあります。フォーカスが隠れるのは、スクロールした後、特定の画面サイズで、初回訪問時だけ出るバナーがあるときです。多くの自動チェックは、ページ上部を一度読み込むだけでTab移動はしません。生成されたレイアウトも、position: sticky を付けるだけで、その分の余白を確保しないことがよくあります。
試してみる
Tabで一覧を下へ進み、Shift + Tabで戻ってください。
フォーカスした記事リンクを目で追ってください。常に見えますか?ヘッダーやCookieバナーの下に隠れませんか?
問題あり 直してみませんか?
再現デモです。「問題あり」は意図的にアクセシブルでない状態にしています。
修正方法
scroll-paddingでバーの高さ分を確保するか、バーをスクロールする領域の外に出します。
- 1どちらのTab方向でも、フォーカス中の要素が固定表示のバーに完全に隠れない。
- 2確保する余白はバー自身の高さから取り、両者を常にそろえる。
- 3公開するすべてのバナー、チャットボタン、拡大率で確認する。
.site-header { position: sticky; top: 0; height: 4rem;}.cookie-banner { position: fixed; inset-inline: 0; bottom: 0; height: 5rem;}ページは両方のバーの下をスクロールしますが、画面の上4remと下5remが覆われていることをブラウザーに伝えていません。フォーカスでスクロールしたリンクは、どちらかのバーの下で止まります。
scroll-padding は、画面のどこが実際に見えているかをブラウザーに伝えます。フォーカスによるスクロール、ページ内リンク、scrollIntoView が、バーの手前で止まります。バーの高さと余白は同じトークンから取るため、ずれません。ただし、バーがその高さを保っている間だけ有効です。狭い幅や文字の拡大でヘッダーの文字が折り返して高くなる場合は、余白も合わせて広げる必要があります。文字と一緒に拡大される rem で高さを決めるか、ResizeObserver で変数を更新してください。また、scroll-padding は実際にスクロールする要素に指定します。本文がコンテナー内でスクロールする場合は、html ではなくそのコンテナーに指定します。
どちらも基準を満たします。scroll-padding は変更が小さく、スクロールに合わせてモバイルのアドレスバーが隠れる動きを含め、通常のページスクロールを保てます。ただし、確保する余白がバーの高さと一致している必要があります。グリッドのレイアウトは高さの計測が不要ですが、スクロールがページから main に移るため、引っ張って更新する操作、スクロール位置の復元、一部の解析スクリプトの動きが変わります。バーの高さが決まっている既存のサイトには scroll-padding を、ページの骨組みを作るときや、バーの高さが内容で変わる場合はレイアウトの変更を選んでください。
ページに重なる要素をすべて数えてください。ヘッダー、Cookieやキャンペーンのバナー、チャットの起動ボタン、「ページ上部へ」ボタンなどです。それぞれに余白を確保するか、スクロール領域の外に置きます。バーに対処しても、隅に浮いたボタンが小さな操作要素を完全に隠すことがあります。
閉じられるバナーでも、表示中は基準を満たしません。消えるまでは余白を確保してください。拡大表示では、高いバーが本文の場所をほとんど残さないことがあります。画面の高さが低いときは、@media (max-height: 30rem) などで position: sticky を外し、ヘッダーが一緒にスクロールするようにすることも検討します。一部だけ隠れたフォーカスはAAの2.4.11を満たしますが、AAAの2.4.12は一切隠れないことを求めます。一部が隠れたフォーカスは読み取りにくいため、要素全体が見えることを目指してください。
修正の確認
マウスを使わない4つの確認
確認方法: キーボード、ズーム
OS、ブラウザーと支援技術のバージョン、ビルド、実施日、各手順の実際の結果を記録してください。ヘッダー、バナー、ページのレイアウトを変更した際は、再度確認します。
制限
このサンプルは、どのアプリケーションでも同じ結果になることを保証するものではありません。現在のブラウザーはフォーカスによるスクロールにも scroll-padding を適用しますが、対象のブラウザーで確認してください。カルーセルやサイドパネルなど、ページ内のスクロール領域には、それぞれ余白の指定が必要です。コード内のトークン名は、実際のデザイントークンに置き換えてください。
よくある問題を再現した学習用のサンプルです。実在のクライアントの診断結果ではありません。コードは出発点となる実装例のため、実際の製品でも確認してください。ここでは支援技術でのテスト結果は報告していません。
コードを更新しても、使いやすさを保つために
ガイドの内容を、コーディングエージェントやCIで使える開発ルールにまとめます。更新後は、キーボードとスクリーンリーダーで再テストし、問題が再発していないか確認します。