css-hidden-focus

フォーカス可能な要素を視覚的に隠してはいけません

manualWCAG 2.4.7 (AA)確度:low重大度:seriousoperable

キーボードでフォーカス可能な要素が、タブ順序に残る可能性のあるCSSの手法で視覚的に隠されていないことを確認します。

適用範囲:タブ移動可能(キーボードでフォーカス可能)でありながら、タブ順序に残る可能性のあるCSSの手法で視覚的に隠されている要素に適用されます。

期待される結果:視覚的に隠された状態(例:opacity:0、クリップ、画面外への配置)の要素は、タブ移動可能にしないことを推奨します。フォーカスを受け取ったときにCSSで表示に戻される要素は、フォーカス中は隠れていないため検出しません。よくあるスキップリンクのパターン(.skip { position: absolute; left: -9999px } .skip:focus { left: 0 })や、フォーカス時に適用されなくなる非表示のルール(.visually-hidden-focusable:not(:focus) { clip: rect(0 0 0 0) })が該当します。別のルールに入れ子になったフォーカスのルール(.skip { &:focus { top: 0 } })は、展開して書いたものとして数えます。フォーカスが:has()の中にあるルールは、その対象については:focus-withinと同じように数えます。!importantでないフォーカスのルールは、要素を隠す!importantの宣言を上書きしません。

検出結果が報告する内容:

  • metrics.visibilityHints:フォーカスを受け取れるまま要素がどのように隠されているかを示します。要素自身のスタイルによる場合はopacityZero、offscreen、clipped、zeroSizeOverflowHidden(サイズがなく、overflowがhidden)のいずれかです。要素自身のスタイルでは表示されている場合は、outOfReach(コンテナーが画面外に配置されている、またはブラウザーで、フォーカスによって表示されるボックスがスクロールしても届かない位置にある)またはcontainerClipped(コンテナーが何もない大きさに切り取られている、サイズがなくoverflowがhiddenである、何もない大きさに縮小されている、またはブラウザーで、フォーカスによってスクロールされないoverflow: clipのコンテナーの完全に外に要素がある)です。
  • runtimeProbe:要素にフォーカスを当てたときに、フォーカスが別の要素へ直接移った場合(cssHiddenTabbable_runtimeRedirect_needsReview)を除いてnullです。移った場合は、redirected: trueと、フォーカスの移動先の要素のタグとid(redirectedToTag、redirectedToId)が入ります。この方法で試すのは、隠された要素の最初の3つだけです。

これらのdata.detailsのフィールドは、検出結果を読み解き、再現するのに役立ちます。reasonCodeと、出力スキーマで安定と明記された一部のフィールドを除き、安定した契約ではありません。マイナーリリースで名前が変わったり、なくなったりすることがあるため、これらに依存した実装はしないでください。

例

can't tell
<a href="/x" style="opacity:0;">Hidden but tabbable link</a>

opacity:0で晴眼のキーボードユーザーには見えないのに、リンクがタブ順序に残っています。

n/a
<a href="/x">Visible link</a>

リンクはフォーカス可能で、かつ見えています。報告するものはありません。

n/a
<style>.skip { position: absolute; left: -9999px; } .skip:focus { left: 0; }</style>
<a class="skip" href="#main">Skip to content</a>

リンクは通常時は画面外にありますが、フォーカスを受け取ると:focusのルールによって表示に戻ります。

確認方法

このルールが判断できない場合はcantTellを報告し、判断を人に委ねます。ルールが投げかける各質問を、理由コードごとに、答えるための手順とともにここに示します。検出結果にも同じ手順がhowToCheckとして、スキャンの言語で含まれます。出力スキーマを参照してください。

cssHiddenTabbable_needsFocusStateVerification

  1. レポートに示された要素のすぐ手前をクリックし、フォーカスが届くはずのところまでTabキーを押してください。
  2. 開発者ツールのコンソールでdocument.activeElementを確認し、フォーカスがその要素にあることを確かめてください。
  3. 画面上でその要素とフォーカスインジケーターを探してください。

満たす場合:フォーカスがある間、要素が表示され、フォーカスインジケーターが見えます。

満たさない場合:要素が隠れたままフォーカスを受け取るため、キーボード利用者にはフォーカスの位置が見えず、WCAG 2.4.7を満たしません。

cssHiddenTabbable_runtimeRedirect_needsReview

  1. レポートに示された要素のすぐ手前をクリックし、フォーカスが届くはずのところまでTabキーを押してください。
  2. フォーカスがどこに移るかを見て、開発者ツールのコンソールでdocument.activeElementを確認してください。
  3. 後ろのコントロールからShift+Tabを押し、フォーカスが隠れた要素で止まるか、そのまま通り過ぎるかを確認してください。

満たす場合:フォーカスが隠れた要素にとどまることはなく、フォーカストラップの番兵要素と同じように、表示されているコントロールへそのまま移ります。

満たさない場合:フォーカスが隠れた要素にとどまることがあるため、キーボード利用者にはフォーカスの位置が見えず、WCAG 2.4.7を満たしません。

ソースコードを見る