本文へ移動
ご相談

Tabキーで到達できないボタン

クリックでしか操作できないため、キーボードでは保存できません。

WCAG 2.1.1WCAG 4.1.2 確認方法 キーボードスクリーンリーダーズーム強制配色 エージェント向けMarkdown
問題あり Tabキーで移動できない。
修正後 Tabキーで移動できる。
同じ操作部品の、修正前と修正後。
01

問題

キーボード利用者が、作業内容を保存できません。

場面 Tabキーで保存ボタンに移動できない。 詳しく読む閉じる

設定画面の保存操作はボタンのように見えます。クリックでは保存できますが、Tabキーは最後の入力欄からフッターへ移ります。

確認できる問題 button要素ではなく、クリック処理だけを持つdiv。 詳しく読む閉じる

クリックイベントを設定したdiv要素を使っています。HTML標準のボタンが持つ役割やキーボード操作には対応していません。

利用者への影響 キーボードや音声で操作する人が保存できない。 詳しく読む閉じる

キーボード利用者はポインター利用者と同じ操作を完了できません。音声操作でも適切な名前がない場合があります。

自動チェックとAIの限界 role="button"でスキャンは通っても、Enterは動かない。 詳しく読む閉じる

スキャナーがクリック要素を検出しても、role="button" の追加後にEnter・Spaceが一度だけ動くか、フォーカスや保存結果が伝わるかまでは証明できません。生成されたコードも、実際の操作で確認が必要です。

02

試してみる

TabとEnterで、カートに追加してください。

Tabキーで「カートに追加」へ移動し、EnterまたはSpaceを押してください。

カート内: 0

再現デモです。「問題あり」は意図的にアクセシブルでない状態にしています。

03

修正方法

divをbutton要素に置き換え、見た目はそのまま保ちます。

  1. 1その場の操作にはtype="button"、フォーム送信にはtype="submit"を使う。
  2. 2既存のスタイルをbuttonに移し、競合する部分だけをリセットする。
  3. 3結果は、最初からページにあるステータス領域で伝える。
修正前 クリックだけに反応するdiv
<div class="save-control" onclick="saveSettings()">変更を保存</div>
修正にならない応急処置
<div class="save-control" role="button" tabindex="0" onclick="saveSettings()">変更を保存</div>
修正後 Button要素を使う

html

<button type="button" class="save-control">変更を保存</button><p id="save-status" role="status"></p>

css

.save-control {  font: inherit;  /* 既存の余白、色、角丸はここに残します。 */}.save-control:focus-visible {  outline: 3px solid var(--focus-ring);  outline-offset: 3px;}

js

const button = document.querySelector('.save-control');button.addEventListener('click', async () => {  await saveSettings();  document.getElementById('save-status').textContent = '設定を保存しました。';});
この修正で直る理由

div要素はTabキーで移動できず、役割もなく、EnterやSpaceにも反応しません。ボタンに見えるのは、画面が見えてポインターを使える人だけです。

button要素のクリック処理は、EnterやSpaceでも実行されるため、キー操作の処理は不要です。ステータス領域は、文字を変更する前からページに置いておく必要があります。後から追加すると、結果が読み上げられない場合があります。

修正にならない応急処置

スキャナーやコーディングアシスタントがよく提案する変更です。フォーカスでき、ボタンとして読み上げられるようになりますが、EnterやSpaceでは何も起きません。手作業で完成させるには、キー操作の処理、キーを離したときに動くSpace、スクロールの抑止、無効状態の扱いが必要です。button要素なら、これらはすべて最初から備わっています。

実装の判断

フォーム内のbutton要素は、typeを省略すると送信ボタンになります。フォームを送信しない操作には type="button"、送信は type="submit" を指定します。切り替えボタンでは名前を変えず、aria-pressed で状態を示します。別のページへ移動する操作には、リンクを使います。

既存の書体、余白、形はbutton要素に引き継ぎます。ブラウザーが独自のボタンスタイルを付けるため、divに戻すのではなく、デザインと合わない部分だけをリセットしてください。

再発を防ぐため、コンポーネントライブラリーでは標準のbutton要素を基本にします。コードレビューでは、その操作が処理を実行するのか、別のページへ移動するのかを確認します。処理にはボタン、移動にはリンクを使います。

04

修正の確認

マウスを使わない5つの確認

5件中0件を確認済み

OS、ブラウザーと支援技術のバージョン、ビルド、実施日、各手順の実際の結果を記録してください。共通のボタンコンポーネントを変更した際は、再度確認します。

制限

このサンプルは、どのアプリケーションでも同じ結果になることを保証するものではありません。アプリケーション固有のデータ処理は省略しています。実際に使用する支援技術で、操作全体を確認してください。

よくある問題を再現した学習用のサンプルです。実在のクライアントの診断結果ではありません。コードは出発点となる実装例のため、実際の製品でも確認してください。ここでは支援技術でのテスト結果は報告していません。

参考資料: www.w3.org

コードを更新しても、使いやすさを保つために

ガイドの内容を、コーディングエージェントやCIで使える開発ルールにまとめます。更新後は、キーボードとスクリーンリーダーで再テストし、問題が再発していないか確認します。

再テストの進め方