WCAG 達成基準 · Level A

WCAG 2.4.3: フォーカス順序

WCAG 2.4.3 は、ウェブページが順次ナビゲート可能であり、そのナビゲーションの順序が意味や操作に影響する場合、フォーカス可能なコンポーネントは意味と操作性を損なわない順序でフォーカスを受けなければならないと定めています。この基準は、コンテンツを理解し操作するために、論理的で予測可能なフォーカス順序に依存しているキーボード利用者や支援技術利用者にとって不可欠です。

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

WCAG 2.4.3 Focus Order は、Operable(操作可能)という原則の下にあるレベルAの達成基準です。そこでは次のように述べられています。「Webページを順次ナビゲートでき、そのナビゲーションの順序が意味や操作に影響する場合、フォーカス可能なコンポーネントは、意味と操作性を維持する順序でフォーカスを受け取る。」

実務的には、ユーザーがページ上のインタラクティブ要素 — リンク、ボタン、フォームフィールド、カスタムウィジェット、その他のフォーカス可能なコンポーネント — を移動するためにTabキーを押したとき、それらの要素がフォーカスを受け取る順序が論理的でなければならない、ということを意味します。ユーザーが、フォームの途中からフッターのリンクへ、次にモーダルのボタンへ、さらにナビゲーションメニュー項目へと、予期せず飛ばされるようなことがあってはなりません。

この達成基準は、キーボードのみのユーザーやスクリーンリーダーユーザーがページを移動する主な方法である順次キーボードナビゲーションに適用されます。ブラウザにおけるフォーカス順序のデフォルトの情報源はDOM順序です。CSS や JavaScript が意図的にその順序を変更しない限り、要素は Document Object Model(DOM)内に現れる順番でタブシーケンスに現れます。CSS Flexbox や Grid の並べ替えによって視覚的レイアウトが DOM 順序と乖離した場合や、tabindex の値によって不自然なシーケンスが強制される場合に問題が発生します。

合格とみなされるもの: フォーカス順序は論理的で意味のあるものでなければなりません。視覚的な読み順と完全に一致している必要はありませんが、ユーザーがページを理解し操作できる程度には一貫している必要があります。モーダルダイアログが開かれたときにフォーカスを自分自身に移し、開いている間はフォーカスを内部に閉じ込め、閉じたときにトリガーとなった要素にフォーカスを戻す場合、この基準を満たします。マルチステップフォームで、Tab キーがユーザーが入力する順序(左から右に読む言語では上から下、左から右)で各フィールドを進んでいく場合も合格です。

不合格とみなされるもの: ログインフォームの「Username」フィールドから、まったく無関係なプロモーションバナーへフォーカスが飛び、その後で「Password」フィールドに到達するような場合は不合格です。シングルページアプリケーションでダイアログを開いてもフォーカスが背景ページに残ったままの場合も不合格です。ページ全体で不合理なタブシーケンスを強制する正の整数の tabindex 値(例: tabindex='2'tabindex='5')を使用することも不合格です。

公式の例外: WCAG は、意味と操作性が維持されている限り、フォーカス順序が視覚的な読み順と一致している必要はないと明示しています。また、ナビゲーションの順序が意味や操作に影響しない場合 — 例えば、フォーカス可能な要素が1つしかないページでは評価すべきシーケンスが存在しない — も許容されています。さらに、意味を維持する複数の妥当な順序が存在する場合、それらのいずれも許容されます。

フォーカス順序に影響する主な HTML および JavaScript の仕組みには、インタラクティブ要素の自然な DOM 順序、tabindex 属性(特に正の整数値)、DOM を変更せずに視覚レイアウトを並べ替える CSS プロパティ(Flexbox/Grid の orderposition: absolutefloat など)、JavaScript によるフォーカス管理(要素に対する .focus() の呼び出し)、明示的なフォーカス管理を必要とする ARIA ダイアログパターンなどがあります。

なぜ重要なのか

フォーカス順序は些細な技術的詳細ではなく、多くのユーザーにとってウェブのナビゲーションの背骨となるものです。複数の異なる障害当事者グループが、デジタルプロダクトを効果的に利用するために論理的なフォーカスシーケンスに依存しています。

マウスを使えない運動障害のあるユーザーは、キーボード(または sip-and-puff スイッチ、ヘッドポインタ、視線入力システムなどのキーボード相当デバイス)のみに頼ってナビゲートします。これらのユーザーにとって、乱れたフォーカス順序は単なる不便ではなく、ページを完全に利用不能にすることがあります。Tab キーがユーザーをページの誤った部分へ連れて行く場合、必要なコントロールに効率的に到達する手段がなく、単に手を動かして別の場所をクリックすることもできません。

NVDA、JAWS、VoiceOver などのスクリーンリーダーを使用する全盲およびロービジョンのユーザーは、フォーカスが当たった要素を音声で聞きます。論理的なフォーカス順序であれば、彼らが受け取る音声ストリームはインターフェースの意図された流れを反映します。フォーカスが不規則に飛び回ると、ユーザーはページ上の自分の位置に関するメンタルモデルを失ってしまいます。世界保健機関によると、世界で約22億人が何らかの視覚障害を抱えており、そのうちスクリーンリーダーを使用する多くの人にとって、フォーカス順序はページ構造を体験する主な手段です。

認知障害のあるユーザーも、予測可能なフォーカスシーケンスから恩恵を受けます。フォーム入力の途中で予期しないフォーカスジャンプが起こると、混乱を招き、ワークフローのやり直しを強いられたり、必須フィールドを見落としたりする可能性があります。注意力の問題や短期記憶の課題を抱えるユーザーは、サイト利用に自信を持つために、一貫性があり予測可能なナビゲーションを必要とします。

具体的な現実のシナリオ: トルコのECサイトのチェックアウトページを想像してください。ビジュアルデザインでは CSS Grid を使って、左側に注文概要、右側に支払いフォームを配置しています。しかし DOM では、支払いフォームが先に、注文概要が後に配置されています。視覚的レイアウトは視覚のあるマウスユーザーにとっては正しく見えますが、キーボードユーザーが Tab キーを押すと、注文概要を確認する前に支払いフォームのフィールドにフォーカスが当たります。その結果、誤った注文を知らないうちに確定してしまうかもしれません。さらに悪いことに、正の tabindex の誤った管理により、「Apply Coupon」フィールドより先に「Confirm Purchase」ボタンがフォーカスを受け取る場合、ユーザーは割引を適用するつもりだった購入を誤って送信してしまう可能性があります。これは、フォーカス順序の破綻が直接的かつ現実の金銭的損失につながる例です。

アクセシビリティの観点を超えても、論理的なフォーカス順序は、速度のためにキーボードナビゲーションを好むパワーユーザーの体験を向上させます。また、SEOも間接的に支援します。自然なフォーカス順序を生み出すよく構造化された DOM は、検索エンジンがコンテンツの階層や重要度を理解するために利用する意味的に適切なマークアップを反映していることが多いからです。

関連する Axe-core のルール

WCAG 2.4.3 の最終的な評価には手動テストが必要です。axe-core のような自動化ツールは、特定のフォーカスシーケンスが「意味と操作性を維持している」かどうかをアルゴリズム的に判断することはできません。その判断には、ページの目的やコンテンツの関係性を理解している人間が必要です。しかし、axe-core や関連ツールは、フォーカス順序の問題を強く示唆する特定のパターンにフラグを立てることができます。

  • tabindex(正の値) — ヒューリスティックなフラグ: 一部のリンティングや監査ツールは、要素に正の整数の tabindex 値(0より大きい値)が付与されている場合に警告を出します。正の tabindex 値は自然な DOM 順序を上書きし、それらの要素をタブシーケンスの先頭に配置しますが、これはほとんどの場合、不合理で予測不能なフォーカス順序を生み出します。axe-core のコアルールセットには(シーケンスの論理的妥当性を計算できないため)専用の「focus-order」自動ルールは含まれていませんが、axe DevTools Pro や手動監査では、代理指標として正の tabindex の使用を特にチェックします。
  • scrollable-region-focusable: Axe-core には、スクロール可能な領域でキーボードフォーカスが当てられないものにフラグを立てるルールがあります。これは直接のフォーカス順序ルールではありませんが、フォーカスを受け取れないスクロール領域は全体のナビゲーションシーケンスを破壊し、キーボードユーザーが必要なコンテンツを飛ばしてしまう原因になります。
  • CSS によって並べ替えられたコンテンツの手動検査: 自動ツールは、CSS Flexbox の order や Grid の配置によって視覚順序と DOM 順序の不一致が生じているかどうかを検出できません。人間のテスターが、画面上のレイアウトと、キーボードナビゲーション中に観察されるフォーカスシーケンスを目視で比較する必要があります。これは、モダンなレスポンシブデザインにおける 2.4.3 の失敗の最も一般的な原因であり、自動スキャナからは完全に見えません。
  • 動的コンテンツにおける JavaScript フォーカス管理の手動検査: シングルページアプリケーション、インフィニットスクロール、モーダル、フライアウトメニューなどは、コンテンツの変化に応じてフォーカスを適切に移動させるために JavaScript を必要とします。自動ツールは DOM の静的なスナップショットを実行するだけで、これらのフォーカス管理シナリオを引き起こすために必要なユーザー操作のシーケンスをシミュレートできません。モーダルが新たに開かれたときにフォーカスがそこへ移動し、閉じたときに正しいトリガーへ戻り、ユーザーがアクセス不能な背景レイヤーに取り残されないことを検証できるのは、手動のキーボードテストだけです。

テスト方法

  1. 出発点としての自動スキャン: ページに対して axe DevTools(ブラウザ拡張)または Google Lighthouse を実行します。正の tabindex 値やフラグが立てられたスクロール領域に関する警告を探します。自動テストで問題なしと出ても、2.4.3 が満たされているとは限らないことに注意してください。手動テストは常に必要です。フラグが立てられた問題は、後で詳しく調査できるよう記録しておきます。
  2. マウスを外し、Tab のみでナビゲートする: ブラウザのアドレスバーまたはページ上部から開始し、Tab キーを繰り返し押して、すべてのフォーカス可能な要素を移動します。そのシーケンスを注意深く観察します。フォーカスは、ページの論理的な読み順やインタラクションの流れに合った順序で移動しているか、自問してください。フォーカスが予期しない領域に飛ぶことはないか、意図的なダイアログ内を除いて、前後に移動できなくなる(フォーカスが閉じ込められる)ことはないかを確認します。
  3. 動的コンポーネントをテストする: キーボードを使って、モーダル、ダイアログ、ドロップダウンメニュー、アコーディオン、タブパネル、日付ピッカー、その他のインタラクティブウィジェットを起動します。起動と同時にフォーカスが新たに表示されたコンテンツに移動することを確認します。ダイアログを閉じた後、フォーカスがページの先頭や任意の位置ではなく、そのダイアログをトリガーした要素に戻ることを確認します。
  4. NVDA + Firefox でテストする: NVDA を起動し、Firefox を立ち上げてページに移動します。Tab キーでインタラクティブ要素を移動し、読み上げ内容を聞きます。読み上げられるシーケンスが文脈的に意味をなしているか確認します。NVDA のブラウズモード(矢印キー)を使って静的コンテンツを読み、読み順がそのコンテンツ内のインタラクティブ要素のフォーカス順序と整合しているか確認します。
  5. VoiceOver + Safari(macOS/iOS)でテストする: VoiceOver を有効にし、Tab(デスクトップ)またはスワイプジェスチャー(iOS)でフォーカス可能な要素を移動します。フォーカスシーケンスが論理的であることを確認します。iOS では、モーダルやオーバーレイがフォーカスを適切に閉じ込め、閉じたときにフォーカスを戻すことをテストします。
  6. JAWS + Chrome でテストする: JAWS の Tab ナビゲーションを使用し、読み上げられるフォーカスシーケンスが一貫していることを確認します。JAWS の仮想カーソルを使って読み順とインタラクティブなフォーカス順序を照合し、不一致がないかを特定します。
  7. DOM と視覚レイアウトを比較検査する: ブラウザの DevTools を開き、DOM 構造を確認します。DOM 内のインタラクティブ要素の順序と、画面上での視覚的な位置を比較します。orderposition: absolutefloat などの CSS プロパティによって大きな差異が生じている場合、タブシーケンスを手動で追跡し、意味や操作性に影響が出ていないかを判断します。
  8. DOM 内の tabindex 値を確認する: ブラウザコンソールで document.querySelectorAll('[tabindex]') を実行し、明示的な tabindex 属性を持つすべての要素を一覧表示します。正の整数値を持つ要素を調査し、変更されたタブ順序におけるその配置が論理的かどうかを評価します。

修正方法

正の tabindex 値が不合理な順序を作る — 誤り

<!-- Positive tabindex values force an unnatural tab sequence -->
<form>
  <label for='email'>Email</label>
  <input type='email' id='email' tabindex='3'>

  <label for='name'>Full Name</label>
  <input type='text' id='name' tabindex='1'>

  <label for='phone'>Phone</label>
  <input type='tel' id='phone' tabindex='2'>

  <button type='submit' tabindex='4'>Submit</button>
</form>
<!-- Tab order: Full Name → Phone → Email → Submit
     Visual/logical order: Email → Full Name → Phone → Submit
     This mismatch breaks focus order. -->

正の tabindex 値が不合理な順序を作る — 正しい例

<!-- Remove all positive tabindex values; rely on DOM order.
     Rearrange DOM to match the logical sequence. -->
<form>
  <label for='email'>Email</label>
  <input type='email' id='email'>

  <label for='name'>Full Name</label>
  <input type='text' id='name'>

  <label for='phone'>Phone</label>
  <input type='tel' id='phone'>

  <button type='submit'>Submit</button>
</form>
<!-- Tab order now follows DOM order: Email → Full Name → Phone → Submit
     Matches logical and visual order. No tabindex needed. -->

CSS による視覚的な並べ替えと DOM 順序の不一致 — 誤り

<!-- DOM has sidebar first, main content second.
     CSS uses flexbox order to visually flip them.
     Keyboard users tab through sidebar links before main content links,
     which does not match what a sighted user sees first. -->
<style>
  .layout { display: flex; }
  .sidebar { order: 2; } /* Visually shown on the right */
  .main    { order: 1; } /* Visually shown on the left */
</style>

<div class='layout'>
  <nav class='sidebar'>
    <a href='/about'>About</a>
    <a href='/contact'>Contact</a>
  </nav>
  <main class='main'>
    <a href='/article'>Read Article</a>
  </main>
</div>
<!-- Focus order: About → Contact → Read Article
     Visual order: Read Article → About → Contact
     Mismatch breaks 2.4.3 -->

CSS による視覚的な並べ替えと DOM 順序の不一致 — 正しい例

<!-- Fix: reorder the DOM to match the intended visual and logical order.
     Remove the CSS 'order' overrides that caused the mismatch. -->
<style>
  .layout { display: flex; }
  /* No 'order' overrides — DOM order determines both visual and tab order */
</style>

<div class='layout'>
  <main class='main'>
    <a href='/article'>Read Article</a>
  </main>
  <nav class='sidebar'>
    <a href='/about'>About</a>
    <a href='/contact'>Contact</a>
  </nav>
</div>
<!-- DOM order, visual order, and focus order now all match. -->

モーダルダイアログがフォーカスを管理していない — 誤り

<!-- Button opens a modal, but focus stays on the background page.
     Keyboard users cannot interact with the dialog. -->
<button id='open-modal' onclick='document.getElementById("dialog").style.display="block"'>
  Open Settings
</button>

<div id='dialog' style='display:none;'>
  <h2>Settings</h2>
  <label for='theme'>Theme</label>
  <select id='theme'>
    <option>Light</option>
    <option>Dark</option>
  </select>
  <button id='close-modal'>Close</button>
</div>
<!-- When dialog opens, focus remains on #open-modal in the background.
     Tab continues to background page elements, not dialog elements. -->

モーダルダイアログがフォーカスを管理していない — 正しい例

<!-- Focus is moved into the dialog on open and returned to trigger on close.
     role='dialog' and aria-modal='true' inform screen readers of the context. -->
<button id='open-modal'>Open Settings</button>

<div id='dialog'
     role='dialog'
     aria-modal='true'
     aria-labelledby='dialog-title'
     style='display:none;'>
  <h2 id='dialog-title'>Settings</h2>
  <label for='theme'>Theme</label>
  <select id='theme'>
    <option>Light</option>
    <option>Dark</option>
  </select>
  <button id='close-modal'>Close</button>
</div>

<script>
  const openBtn = document.getElementById('open-modal');
  const dialog  = document.getElementById('dialog');
  const closeBtn = document.getElementById('close-modal');

  openBtn.addEventListener('click', () => {
    dialog.style.display = 'block';
    // Move focus to first focusable element in dialog
    document.getElementById('theme').focus();
  });

  closeBtn.addEventListener('click', () => {
    dialog.style.display = 'none';
    // Return focus to the element that triggered the dialog
    openBtn.focus();
  });
</script>
<!-- Focus order is now logical: trigger → dialog contents → back to trigger. -->

よくある間違い

  • フォーカス順序を「制御」する目的で正の整数の tabindex 値(例: tabindex='1'tabindex='5')を使用すること。DOM 構造を正す代わりにこれを行うと、ページ内のすべての自然にフォーカス可能な要素よりも前にそれらの要素が配置され、極めて維持が難しく、ほぼ必ずエラーを生む混沌としたグローバルなタブシーケンスを作り出します。
  • DOM を並べ替えずに、Flexbox や CSS Grid の CSS order を使ってコンテンツを視覚的に並べ替えること、そしてキーボードナビゲーションのテストを怠ること。視覚ユーザーにはレイアウトが正しく見えても、タブシーケンスは視覚順序ではなく DOM 順序に従います。これはキーボードユーザーにとって見えないが重大な不整合です。
  • JavaScript の .focus() メソッドを使って、モーダルやダイアログを開いたときにプログラム的にフォーカスを移動しないこと。スクリーンリーダーやキーボードユーザーは背景コンテンツに取り残され、ダイアログを見つけたり操作したりできないことがよくあります。
  • モーダル、ドロワー、ドロップダウンを閉じた後に、フォーカスをトリガー要素に戻さないこと。フォーカスをページの先頭に戻したり、すでに非表示になっている要素に残したりすると、ユーザーは長いページの最初から再度ナビゲートし直さなければならず、自分の位置を失ってしまいます。
  • 動的に読み込まれるコンテンツ(インラインエラーメッセージ、トースト通知、遅延読み込みセクションなど)を、視覚的にはその前にあるフォーカス可能要素の後に DOM に挿入すること。その結果、キーボードユーザーは新しいコンテンツに順序外で遭遇するか、まったく遭遇しない可能性があります。
  • tabindex='-1' を使って要素をタブシーケンスから外しながら、代替のキーボードアクセス手段を提供しないことtabindex='-1' 自体は有効なツール(要素をプログラム的にフォーカス可能にしつつ自然なタブ順序から外す)ですが、ユーザーが本当にアクセスする必要のあるコントロールに誤って適用すると、キーボードユーザーからそのコントロールを事実上隠してしまいます。
  • シングルページアプリケーションのルート遷移で、フォーカスを新しいページ見出しやスキップナビゲーションのランドマークではなく、document body やブラウザのクロームにリセットすること。その結果、ユーザーはルートが変わるたびにナビゲーション全体を Tab で通過しなければなりません。
  • 矢印キーによるナビゲーションが実装されておらず、Tab キーで隠れたスライドを1枚ずつ移動してしまうカスタムカルーセルやスライダーウィジェットを実装すること。これにより、ユーザーは次のページコンテンツに到達する前に、画面外の要素を何十個も Tab で通過しなければならなくなります。
  • 常に display:none の「見えない」スキップナビゲーションリンクを DOM に配置すること.sr-only / clip テクニックによる視覚的非表示ではなく)。display:none のリンクはタブ順序から完全に除外されるため何の役にも立ちません。一方、適切に実装されたスキップリンクは Tab でフォーカスを受け取り、可視化され、メインコンテンツへの論理的なフォーカスフローを直接支援します。
  • インタラクティブ要素の中に別のインタラクティブ要素をネストすること(例えば、<a> タグの中に <button> を入れるなど)。これはブラウザごとに一貫しないタブ挙動を生み、同じ論理的コントロールにフォーカスが複数回当たったり、まったく当たらなかったりする原因になります。

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

WCAG 2.4.3 Focus Order は、トルコの画期的なアクセシビリティ法制である大統領通達 2025/10と直接関係しています。この通達は 2025年6月21日付官報第 32933 号で公布され、トルコで事業を行う幅広い公的・民間主体に対して、国際的に認められたガイドライン — 2.4.3 を含むすべての WCAG 2.x レベルA達成基準 — への適合を義務付けるウェブアクセシビリティ基準を定めています。

この通達は幅広い主体を対象としています。公的機関 — 省庁、自治体、国立大学、政府機関など — は、通達の公布日から1年以内に完全な適合を達成しなければなりません。対象となる民間部門の事業者は、同じ適合水準に2年以内に到達する必要があります。対象となる民間部門のカテゴリには、ECプラットフォーム、銀行および金融機関、病院および民間医療提供者、20万以上の加入者を持つ通信会社、旅行代理店、民間交通事業者、国民教育省(MoNE)の認可の下で運営される私立学校が含まれます。

これらすべての組織にとって、壊れた、あるいは不合理なフォーカス順序は単なるユーザビリティの欠点ではなく、この通達の執行規定の下で法的・行政的な結果を招きうる規制違反です。例えば、トルコの銀行のオンラインバンキングポータルで、送金画面のフォーカス順序が金額フィールドから確認ボタンへ飛び、受取人の IBAN フィールドを飛ばしてしまうとします。キーボードのみを使用するユーザー — 例えば運動障害のある顧客 — は、必要なフィールドを正しく入力しないまま誤って送金を開始してしまう可能性があります。このシナリオは、同時に WCAG 2.4.3 の失敗であり、通達の要件違反であり、ユーザーにとって潜在的に重大な金銭的被害を意味します。

同様に、この通達の対象となる EC サイトが、視覚的に魅力的な商品ページを表示するために CSS Grid の並べ替えを使用しているものの、タブシーケンスが「Add to Cart」ボタンに到達する前に商品画像からフッターリンクへ飛んでしまう場合、これは 2.4.3 に明確に違反しており、したがって通達に非準拠となります。1年および2年の期限があるため、組織はフォーカス順序の是正をアクセシビリティロードマップにおける優先事項として扱うべきであり、先送りする改善事項として扱うべきではありません。フォーカス順序の問題は、DOM 構造や JavaScript のインタラクションパターンに関するアーキテクチャ上の決定に起因することが多いため、開発プロセスの早い段階で対処する方が、リリース後に後付けで修正するよりもはるかにコストがかかりません。

Accsible のオーバーレイ SDK は、構成可能なフォーカス管理の強化を提供することで、組織がコンプライアンスに向けて進むのを支援しますが、オーバーレイソリューションは、アプリケーション自身のコードベースにおける適切なセマンティック HTML 構造と責任あるフォーカス管理と併用したときに最も効果を発揮することに留意することが重要です。大統領通達 2025/10 に対する持続可能で監査可能な適合を達成するには、基盤となるプロダクトが、正しい開発プラクティスによって 2.4.3 を満たしている必要があります。