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

<button><input> などの標準の HTML 要素には、キーボード ユーザー補助機能が無料で組み込まれています。ただし、カスタム インタラクティブ コンポーネントを作成する場合は、tabindex 属性を使用してキーボードから確実にアクセスできるようにします。

コントロールがキーボードにアクセスできるかどうかを確認する

Lighthouse のようなツールは、ユーザー補助機能に関する特定の問題を検出するのに優れていますが、中には人間にしかテストできないものもあります。

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

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

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 > [オプション] > [ユーザー補助])を実行し、「[tabindex] の値が 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>

TODO: DevSite - 思考とチェックの評価

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

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