Tabindex でフォーカスを制御する

<button><input> などの標準的な HTML 要素にはキーボード ユーザー補助機能が組み込まれているため、可能な限り使用する必要があります。ただし、カスタムのインタラクティブ要素を作成する必要がある場合は、tabindex を追加することで、想定されるユーザーの行動を作成できます。

対応ブラウザ

  • 1
  • 12
  • 1.5
  • 4 以下

ソース

tabindex はインタラクティブなコンテンツにのみ追加します。重要な画像などのコンテンツが重要な場合でも、スクリーン リーダーのユーザーはフォーカスを追加しなくてもそのコンテンツを理解できます。

tabindex とは

組み込み要素によって提供されるデフォルトのタブ順序を変更する必要がある場合は、tabindex HTML 属性を使用して要素のタブ位置を明示的に設定できます。

tabindex はどの要素にも適用できますが、インタラクティブな要素にのみ適用し、整数値の範囲を取ります。tabindex を使用すると、フォーカス可能なページ要素の明示的な順序の指定、通常はフォーカスできない要素をタブオーダーに挿入して、タブオーダーから要素を削除できます。次に例を示します。

tabindex="0": 自然なタブオーダーに要素を挿入します。Tab キーを押すことで要素をフォーカスでき、focus() メソッドを呼び出して要素にフォーカスできます。

tabindex="-1": 自然なタブオーダーから要素を削除しますが、focus() メソッドを呼び出して要素にフォーカスを合わせることは可能です。

tabindex="5": 0 より大きい tabindex を指定すると、その要素が自然なタブオーダーの前に表示されます。tabindex が 0 より大きい要素が複数ある場合は、0 より大きい最小値から順にタブオーダーが上がっていきます。0 より大きい tabindex を使用すると、アンチパターンとみなされます。

キーボードで操作できることを確認する

Lighthouse などのツールはユーザー補助に関する特定の問題を自動的に検出できる点で優れていますが、一部のテストは依然として人が手動で行う必要があります。

Tab キーを押して、サイト内を移動してみてください。このページのすべてのインタラクティブ コントロールにアクセスできるか。そうでない場合は、tabindex を使用して、これらのコントロールのフォーカス可能性を改善する必要があります。

ページレベルでフォーカスを管理する

tabindex はシームレスなユーザー エクスペリエンスの実現に役立ちます。たとえば、複数のコンテンツ セクションを含む堅牢な単一ページを作成し、ページ読み込みのさまざまな時点で一部のコンテンツが非表示になっている場合などです。つまり、ページが更新されることなく、ナビゲーション リンクによって表示されるコンテンツが変更されている可能性があります。

この場合は、選択したコンテンツ エリアを特定し、tabindex-1 にして、その focus メソッドを呼び出します。これにより、コンテンツが通常のタブオーダーに表示されなくなります。この手法はフォーカスの管理と呼ばれ、ユーザーが認識したコンテキストをサイトのビジュアル コンテンツと同期した状態に維持します。

コンポーネントのフォーカスの管理

場合によっては、カスタム要素などを使用して、コントロール レベルでフォーカスを管理する必要があります。

どのキーボード動作を実装すべきかを判断するのは難しい場合があります。Accessible Rich Internet Applications(ARIA)Authoring Practices ガイドには、コンポーネントのタイプと、コンポーネントがサポートするキーボード操作の種類が記載されています。

タブオーダーに要素を挿入する

tabindex="0" を使用して、ナチュラル タブオーダーに要素を挿入します。次に例を示します。

<div tabindex="0">Focus me with the TAB key</div>

要素をフォーカスするには、Tab キーを押すか、要素の focus() メソッドを呼び出します。

タブオーダーから要素を削除する

tabindex="-1" を使用して要素を削除します。次に例を示します。

<button tabindex="-1">Can't reach me with the TAB key!</button>

これにより、通常のタブオーダーから要素が削除されますが、focus() メソッドを呼び出すことで引き続き要素にフォーカスできます。

要素に tabindex="-1" を適用しても、その子は自然にタブオーダー内にある場合、または tabindex 値が原因である場合、その子はタブオーダーに残ります。タブオーダーから要素とそのすべての子を削除するには、WICG の inert ポリフィルの使用を検討してください。ポリフィルは、指定された inert 属性の動作をエミュレートします。これにより、支援技術による要素の選択や読み取りができなくなります。

tabindex > 0 を避ける

tabindex が 0 より大きい場合、要素は自然なタブオーダーの前に移動します。tabindex が 0 より大きい要素が複数ある場合は、0 より大きい最小値から順にタブオーダーが上がってきます。

スクリーン リーダーはタブ順ではなく DOM 順にページを移動するため、0 より大きい tabindex を使用するとアンチパターンとみなされます。タブオーダーのより早い位置に要素を配置する必要がある場合は、その要素を DOM 内の早い位置に移動する必要があります。

Lighthouse では、tabindex が 0 より大きい要素を識別できます。ユーザー補助機能の監査([Lighthouse] > [Options] > [Accessibility])を実行し、「Noelement has a [tabindex] value than 0」の監査結果を確認します。

tabindex の移動」を使用

複雑なコンポーネントを作成している場合は、フォーカス以外のキーボード サポートの追加が必要になることがあります。可能であれば、組み込みの select 要素を使用します。フォーカス可能で、矢印キーで他の選択可能なオプションを表示することもできます。

同様の機能を独自のコンポーネントに実装するには、「tabindex の移動」と呼ばれる手法を使用できます。tabindex の移動は、現在アクティブな子を除くすべての子に対して tabindex を -1 に設定することで機能します。コンポーネントはキーボード イベント リスナーを使用して、ユーザーがどのキーを押したかを特定します。

この場合、コンポーネントは、以前フォーカスされていた子の tabindex を -1 に設定し、フォーカスされる子の tabindex を 0 に設定して、その focus() メソッドを呼び出します。

変更前

<div role="toolbar">
  <button tabindex="-1">Undo</button>
  <button tabindex="0">Redo</button>
  <button tabindex="-1">Cut</button>
</div>

変更後

<div role="toolbar">
  <button tabindex="-1">Undo</button>
  <button tabindex="-1">Redo</button>
  <button tabindex="0">Cut</button>
</div>

キーボード アクセスのレシピ

カスタム コンポーネントに必要なキーボード サポートのレベルがわからない場合は、ARIA Authoring Practices 1.1 をご覧ください。このガイドでは、一般的な UI パターンを示し、コンポーネントがサポートするキーを示します。