WCAG 達成基準 · Level AA

WCAG 2.4.7: フォーカスの可視化

WCAG 2.4.7 は、キーボードで操作可能なあらゆるユーザーインターフェイスに、現在どの要素にキーボードフォーカスがあるかをユーザーが常に確認できるよう、視覚的なフォーカスインジケーターを備えることを求めています。これは、キーボードのみを使用するユーザー、運動障害のある人、そしてマウスを使用できないすべての人にとって不可欠です。

このルールが意味すること

WCAG 2.4.7「フォーカスの可視化」は、ウェブページ上のすべてのインタラクティブ要素 ― リンク、ボタン、フォーム入力、カスタムウィジェット、その他あらゆるキーボード操作可能なコンポーネント ― が、キーボードフォーカスを受け取ったときに可視のフォーカスインジケーターを表示することを求めています。平たく言えば、ユーザーが Tab キーを押してページ内を移動するとき、現在どの要素がアクティブなのかを正確に視覚的に確認できなければなりません。

この達成基準は、フォーカスインジケーターの具体的なビジュアルスタイルを義務付けてはいません。必要なのは、何らかの可視の変化が起こることだけです。ただし、背景に溶け込む 1 ピクセルの点線アウトラインのような、ほとんど知覚できないインジケーターは、技術的には 2.4.7 を満たしていても、WCAG 2.2 で導入された、より厳しい WCAG 2.4.11(フォーカスの外観)には不合格となる可能性があります。2.4.7 単体では、識別可能な視覚的変化があれば十分です。

合格とみなされるもの: フォーカスインジケーターは、ページを Tab で移動している見えるユーザーが、スクリーンリーダーの読み上げやその他の非視覚的な手がかりに頼ることなく、どの要素にフォーカスがあるかを特定できる場合に合格となります。一般的に許容される実装には、ブラウザのデフォルトアウトライン、カスタム CSS の outlinebox-shadow のルール、下線の変化、:focus:focus-visible によって適用される背景色の変化などがあります。

不合格とみなされるもの: 開発者が CSS で outline: noneoutline: 0 を使ってブラウザのデフォルトフォーカスリングを削除し、それと同等のカスタムインジケーターを代わりに提供していない場合、不合格となります。また、<div><span> 要素で構築されたカスタムコンポーネントを tabindex でキーボードフォーカス可能にしているにもかかわらず、フォーカス時に可視のスタイル変化がない場合も不合格です。

公式な例外: WCAG は、この達成基準がキーボード操作可能なインターフェイスにのみ適用されると述べています。純粋に装飾目的のコンポーネントや、tabindex='-1' によって明示的にタブ順から除外されているコンポーネントは、通常のキーボードナビゲーションでフォーカスを受け取ることができないため、フォーカスインジケーターを表示する必要はありません。

なぜ重要なのか

フォーカスの可視性はキーボードアクセシビリティの基盤であり、キーボードアクセシビリティは多様な障害当事者へのアクセスの入口です。CDC によると、アメリカ合衆国の成人の約 26% が何らかの障害を抱えて生活しており、その多くがポインティングデバイスではなくキーボードやキーボードエミュレート型の支援技術に依存しています。

運動機能に障害のあるユーザー ― ALS、脳性まひ、反復性ストレス障害、パーキンソン病などの状態を持つ人を含む ― は、キーボード、スイッチデバイス、シップ・アンド・パフコントローラー、視線追跡ソフトウェアなどに頻繁に依存しています。これらすべての入力方法は、ブラウザのキーボードフォーカスモデルに依存しています。フォーカスインジケーターが見えなければ、これらのユーザーはページ上の自分の位置を把握できず、正しいコントロールをアクティブにできず、フォーム送信、購入完了、メニュー操作といった重要なタスクから完全に締め出されてしまう可能性があります。

スクリーンリーダーを使わず、画面拡大を行うことがあるロービジョンのユーザー も、可視のフォーカスに依存しています。ページの一部を拡大表示したとき、可視のフォーカスリングがどの要素がアクティブかを示し、操作の道しるべとなります。

認知障害や注意に関連する障害 にとっても、明確なフォーカスインジケーターは有益です。ADHD や記憶の困難を抱えるユーザーは、複雑なページ上で自分の位置を見失いがちですが、目立つフォーカスインジケーターが信頼できる視覚的なアンカーとなります。

具体的な現実のシナリオとして、多発性硬化症のあるユーザーが、マウス操作の精度が難しくなったためキーボードだけで EC サイトを閲覧している状況を考えてみましょう。ユーザーは商品ページを Tab で移動し、「Add to Cart」ボタンに到達しようとします。もし開発者がフォーカスリングを抑制していた場合、ユーザーにはフォーカスがどこにあるのか全く見えません。Enter キーを押しても(フォーカスが非インタラクティブ要素に当たっていたため)何も起こらないか、誤った操作が実行されます。その結果、フラストレーション、タスクの放棄、そしてビジネスにとっての機会損失が生じます ― すべて、たった 1 行の CSS で防げることです。

障害の有無にかかわらず、マウスの使用が不便な状況では、フォーカスインジケーターはすべてのユーザーにとって有益です。キーボードショートカットで操作するパワーユーザー、外付けマウスを持たないノート PC ユーザー、長いフォームに入力しているユーザーなどです。可視のフォーカスは、セマンティックな HTML と適切なタブ順を促すことで間接的に SEO を改善し、これらは検索エンジンのクローラーに評価されます。

関連する Axe-core のルール

WCAG 2.4.7 には手動テストが必要です。なぜなら、自動ツールはフォーカスインジケーターが見えるかどうかを確実に判断できないからです。Axe-core や類似のエンジンは、outline: none のような CSS ルールの存在は検出できますが、すべてのテーマ、高コントラストモード、ブラウザレンダリングエンジンにまたがるレンダリング結果を評価することはできません。以下はテストの状況を説明したものです。

  • 手動テストが必要 ― focus-visible の抑制: Axe-core には、2.4.7 の不合格を決定的に指摘する専用ルールは同梱されていません。なぜなら、そのためにはページをレンダリングし、すべての要素を Tab で移動し、フォーカスインジケーターのピクセルレベルのコントラスト分析を行う必要があり、これは静的または DOM レベルの解析を超える作業だからです。その代わりに、テスターはページを手動で Tab 移動し、すべてのインタラクティブ要素でフォーカスの変化が視覚的に確認できるかをチェックする必要があります。
  • css-orientation-lock とスタイルチェックからの部分的なシグナル: 一部の axe-core 設定では、スタイルシート内の outline: 0outline: none の存在をベストプラクティス上の警告としてフラグしますが、これはヒューリスティックであり、決定的な違反チェックではありません。なぜなら、そのルールがカスケードのどこかで有効なカスタムフォーカススタイルによって上書きされている可能性があるからです。
  • 自動化が不十分な理由: フォーカスインジケーターは、特定の状態(例: モーダルが開いているとき)でのみ隠れている場合や、特定の要素タイプに対してのみ、あるいは特定のカラーテーマでのみ隠れている場合があります。こうした条件付きの不具合は、実際にレンダリングされた環境で人間のテスターが各インタラクティブ要素をナビゲートし、可視性を確認する必要があります。axe DevTools Pro のようなツールは、outline: none が適用されている要素をハイライトすることで支援できますが、最終的な合否の判断は人間が行わなければなりません。

テスト方法

  1. 自動プレスキャン: ページに対して axe DevTools(ブラウザ拡張または CLI)や Google Lighthouse を実行します。フォーカススタイルに関連するベストプラクティスまたは実験的な警告を探します。これらは 2.4.7 の不合格を決定的に示すものではありませんが、調査すべき要素を浮かび上がらせます。Lighthouse では、「Accessibility」カテゴリでフォーカス関連の指摘を確認します。レポートをエクスポートし、フラグされたすべてのインタラクティブ要素を記録します。
  2. 手動キーボード Tab テスト: マウスを切断するか、手の届かないところに置きます。ページの先頭から Tab キーを繰り返し押し、すべてのインタラクティブ要素 ― リンク、ボタン、入力欄、ドロップダウン、モーダル、タブ、アコーディオン、日付ピッカー ― をナビゲートします。各ステップで、フォーカスされた要素がフォーカスされていない隣接要素と視覚的に区別できることを確認します。フォーカスが当たっても可視の変化が起こらない要素があれば記録します。
  3. 逆方向 Tab テスト: Shift+Tab を使ってページを逆方向にナビゲートし、同じく視覚的なチェックを繰り返します。一部の実装では、CSS の詳細度の問題により、片方向でのみフォーカスの可視性が壊れていることがあります。
  4. NVDA + Firefox テスト: NVDA を起動した状態で Firefox を開きます。ブラウズモード(矢印キー)を使用し、その後フォームコントロールと対話するためにフォームモード(Enter)に切り替えます。NVDA がフォーカスありと読み上げるすべての要素について、画面上にも可視のインジケーターが表示されていることを確認します。これは、支援技術のフォーカスとブラウザのフォーカスの不一致を検出するのに有用です。
  5. VoiceOver + Safari テスト(macOS/iOS): VoiceOver を有効にし、Tab または VO+右矢印でインタラクティブ要素を移動します。画面上のフォーカスリングが VoiceOver の読み上げと一致していることを目視で確認します。
  6. JAWS + Chrome テスト: JAWS を仮想カーソルモードで使用し、その後アプリケーションモードに切り替えます。インタラクティブなコントロールを Tab で移動し、フォーカスされたすべての要素で可視のフォーカスインジケーターが表示されることを確認します。
  7. ハイコントラストモードテスト: Windows のハイコントラストモード(または macOS の「コントラストを上げる」)を有効にし、再度 Tab テストを行います。一部のフォーカスインジケーターは、ハイコントラストテーマで消えてしまう色に依存しています。インジケーターはこれらのモードでも可視でなければなりません。
  8. CSS の検査: ブラウザの DevTools を開き、インタラクティブ要素を選択し、その要素にフォーカスが当たるまで Tab を押してアクティブにし、計算済みスタイルを検査します。outline: noneoutline: 0 が、代わりとなるフォーカススタイルなしに設定されていないことを確認します。また、キーボードによるフォーカスが確実にカバーされるよう、:focus-visible:focus の使い分けも確認します。

修正方法

代替なしのグローバルな outline の抑制 ― 誤り

<!-- すべてのフォーカスインジケーターをグローバルに削除する CSS リセット -->
<style>
  * {
    outline: none; /* すべての要素からフォーカスリングを削除する */
  }
</style>

<a href='/products'>View Products</a>
<button type='submit'>Buy Now</button>

代替なしのグローバルな outline の抑制 ― 正しい例

<!-- グローバルな outline: none リセットを削除する。
     視覚的に明確なカスタムフォーカススタイルを提供する。 -->
<style>
  /* 動きの軽減を好むユーザーを尊重する */
  :focus-visible {
    outline: 3px solid #005fcc;
    outline-offset: 2px;
  }
</style>

<a href='/products'>View Products</a>
<button type='submit'>Buy Now</button>
<!-- これで両方の要素が、キーボードフォーカス時に高コントラストの青いアウトラインを表示する -->

フォーカススタイルのない div ベースのカスタムボタン ― 誤り

<!-- ボタン風にスタイルされた div。フォーカス可能だが :focus の CSS がない -->
<style>
  .fake-btn {
    display: inline-block;
    padding: 10px 20px;
    background: #e00;
    color: #fff;
    cursor: pointer;
  }
  /* :focus や :focus-visible のルールが定義されていない */
</style>

<div class='fake-btn' tabindex='0' role='button'
     onclick='addToCart()' onkeydown='handleKey(event)'>
  Add to Cart
</div>

フォーカススタイルのない div ベースのカスタムボタン ― 正しい例

<!-- カスタムコンポーネントに :focus-visible を追加し、
     キーボードユーザーがフォーカス時に明確なインジケーターを見られるようにする -->
<style>
  .fake-btn {
    display: inline-block;
    padding: 10px 20px;
    background: #e00;
    color: #fff;
    cursor: pointer;
  }
  .fake-btn:focus-visible {
    outline: 3px solid #ffcc00;
    outline-offset: 3px;
  }
</style>

<div class='fake-btn' tabindex='0' role='button'
     onclick='addToCart()' onkeydown='handleKey(event)'>
  Add to Cart
</div>
<!-- 黄色のアウトラインはマウスクリックではなく、キーボードフォーカス時にのみ表示される -->

モーダルオーバーレイ内で隠れてしまうフォーカスリング ― 誤り

<!-- モーダルが overflow:hidden とスタッキングコンテキストを適用し、
     デフォルトのアウトラインをクリップして見えなくしている -->
<style>
  .modal-body {
    overflow: hidden; /* 要素をはみ出すアウトラインをクリップする */
    border-radius: 8px;
  }
</style>

<div class='modal-body'>
  <button>Confirm Order</button>
  <button>Cancel</button>
</div>

モーダルオーバーレイ内で隠れてしまうフォーカスリング ― 正しい例

<!-- outline の代わりに box-shadow を使用し、
     スタッキングコンテキスト内でレンダリングされてクリップされないようにする -->
<style>
  .modal-body {
    overflow: hidden;
    border-radius: 8px;
  }
  .modal-body button:focus-visible {
    /* box-shadow は overflow:hidden ではクリップされず、
       要素自身のボックス内に収まる -->
    box-shadow: 0 0 0 3px #005fcc;
    outline: none; /* 二重リングを避けるためデフォルトを削除 */
  }
</style>

<div class='modal-body'>
  <button>Confirm Order</button>
  <button>Cancel</button>
</div>

よくある間違い

  • どの要素に影響するかを精査せず、ベースの CSS リセットに outline: none を追加すること。 多くの有名なリセット(例: 古いバージョンの normalize.css や Bootstrap のユーティリティ)は、フォーカスリングをグローバルに抑制します。必ず、キーボードユーザー向けに可視性を回復させる明示的な :focus-visible ルールを後続で定義してください。
  • :focus-visible がより適切な場面で :focus のみに依存する、あるいはその逆。 :focus のみを使うと、マウスクリック時にもインジケーターが適用され、見た目が不自然になることがあります。一方、:focus のフォールバックなしに :focus-visible のみを使うと、古いブラウザではインジケーターがまったく表示されない可能性があります。ターゲットとするすべてのブラウザでテストしてください。
  • カスケードを理解しないまま、コンポーネントライブラリのテーマ上書きの中で outline: none を適用すること。 テーマファイル内の 1 つの上書きが、それを継承するすべてのコンポーネント(サードパーティ製ウィジェットを含む)のフォーカスインジケーターを、気づかないうちに消してしまうことがあります。
  • 要素やページ背景に対してコントラストが不十分なフォーカスカラーを使用すること。 白背景に薄いグレーのアウトラインを使うと、技術的にはアウトラインを追加していても、ほとんど知覚できない場合があります。2.4.7 は特定のコントラスト比を義務付けてはいませんが、2.4.11 は義務付けており、開発者が準拠していると考えていても、低コントラストのフォーカスインジケーターが監査不合格の一般的な原因になっています。
  • コンテナに overflow: hiddenclip-path を設定し、ブラウザのデフォルトアウトラインをクリップしてしまうこと。 修正策は、box-shadow ベースのフォーカスインジケーターに切り替えることです。これは要素自身のボックス内でレンダリングされ、親の overflow ルールによってクリップされません。
  • SVG や Canvas コンポーネント内のインタラクティブ要素のフォーカスインジケーターを忘れること。 カスタムチャートのツールチップ、SVG ベースのアイコンボタン、Canvas ベースの描画ツールなどは、ネイティブのフォーカススタイルを持たないことがよくあります。これらには、明示的な ARIA ロール、tabindex:focus-visible の CSS、または JavaScript 駆動の視覚的フィードバックが必要です。
  • 本番用 CSS(例: ポストプロセッサやビルドステップ)でのみフォーカスの可視性を削除し、開発環境では可視のままにしてしまうこと。 これにより、開発チームはローカル QA を通過させてしまう一方で、エンドユーザーには壊れたアクセシビリティを提供してしまいます。
  • SPA のナビゲーションリンクに使われる role='link' の span 要素にはフォーカスインジケーターを適用せず、<a> 要素にだけ適用すること。 ネイティブのタグにかかわらず、キーボードフォーカス可能なすべての要素には可視のフォーカス状態が必要です。
  • モバイルユーザーは常にタッチ操作を行うと想定し、メディアクエリで特定のビューポート幅においてのみフォーカスリングを隠すこと。 Bluetooth キーボードを使うタブレットユーザーや、ランドスケープ表示でキーボード入力に依存するユーザーは、フォーカスインジケーターがまったくない状態に置かれてしまいます。
  • フォーカスリングの表示を防ぐために、プログラムによるフォーカスの直後に JavaScript で .blur() を呼び出すこと。 これはフォーカスの可視性を完全に取り除く重大な誤りであり、デザイン上の近道として決して使ってはなりません。

トルコのアクセシビリティ規制との関係

トルコの 大統領通達 2025/10 は、2025 年 6 月 21 日付官報第 32933 号で公布され、トルコで事業を行う幅広い主体に対して、ウェブおよびモバイルのアクセシビリティ要件を法的拘束力のある形で定めています。この通達は、対象組織に対して WCAG 2.2 レベル AA への適合を義務付けており、WCAG 2.4.7「フォーカスの可視化」は、単なるベストプラクティスではなく、直接的に執行される要件となっています。

通達の対象となる主体には、公共機関・行政機関、EC プラットフォーム、銀行および金融サービス提供者、病院および医療機関、20 万人以上の加入者を持つ通信会社、旅行代理店、民間輸送会社、国民教育省(MoNE)に認可された私立学校が含まれます。これらすべての組織にとって、デジタルインターフェイス上で可視のフォーカスインジケーターを提供しないことは、単なるユーザビリティの不足ではなく、規制上の不適合という問題になります。

Erişilebilirlik Logosu(アクセシビリティロゴ)は、家族・社会サービス省によって発行される公式の認証マークであり、対象組織はこれを表示することで適合を示すことができます。アクセシビリティロゴを取得するには、WCAG 2.2 レベル AA に基づく正式な監査に合格する必要があります。WCAG 2.4.7 は監査人が評価する AA 達成基準の 1 つであり、通常は前述のテストセクションで説明したような手動キーボードテストによって検証されます。サイトがフォーカスリングを抑制していたり、カスタムコンポーネントに可視のフォーカスを実装していなかったりする組織は、このロゴ取得に必要な監査に合格できません。

特にトルコの EC プラットフォームにとって、フォーカスの可視性は直接的な商業的影響を持ちます。アクセシブルなサイトは、キーボードやスイッチアクセスのみで買い物をする運動機能障害のある顧客を含む、より広いユーザーベースにリーチできますし、大統領通達 2025/10 への準拠は、行政措置から組織を守ります。コンポーネントライブラリの段階からフォーカス可視パターンを組み込んでおくことは、監査後に後付けで修正するのではなく、Erişilebilirlik Logosu を維持し、トルコのアクセシビリティ義務を満たすための最も費用対効果の高い方法です。