トピックを検索
マウスでしか切り替えられないタブ
商品ページのタブがクリック処理を付けたリスト項目のため、キーボードでフォーカスできず、どのパネルを表示中かも伝わりません。
<li class="tab active" onclick="show('description')"> 問題
キーボード利用者は最初のタブ以外を開けず、スクリーンリーダー利用者には、タブで内容が切り替わることも、どれを表示中かも伝わりません。
ジャケットの商品ページで、写真の下に「説明」「サイズ」「レビュー(12)」の三つのタブがあります。「サイズ」をクリックすると、説明の代わりにサイズ表が表示されます。ところがTabキーを押すと、フォーカスは三つのタブを飛ばし、説明の中の「お手入れ方法」リンクへ移ります。「サイズ」や「レビュー」を開くキーはありません。スクリーンリーダーでページを読むと、三つの言葉のリストと説明文が読まれるだけで、ほかに二つのパネルがあることは伝わりません。
各タブは、クリック処理を付けた li です。リスト項目は操作要素ではないため、フォーカスを受けず、キーにも反応せず、スクリーンリーダーが読み上げる役割もありません。クリック処理はポインターでしか動かないため、その先のパネルはWCAG 2.1.1「キーボード」を満たしません。選択中のタブは active クラスで示していますが、これを読むのはスタイルシートだけです。これらの言葉がタブであること、下のパネルを切り替えること、どれが選択中かがコードに一切ないため、4.1.2「名前(name)・役割(role)・値(value)」も満たしません。
商品ページ、アカウント設定、料金表では、利用者が求める情報が2番目や3番目のタブにあることがよくあります。タブがマウスでしか動かないと、使えない人は近道を失うのではなく、内容そのものを失います。
10グループ中2グループに影響
クリック処理とTabの移動順を比べる自動チェックなら、クリックには反応するのにフォーカスを受けないリスト項目を見つけられます。しかし、選択中の状態が伝わるか、別のタブを選んだときに状態が移るか、矢印キーが動くかまでは分かりません。AIによるコード生成では、同じリスト項目に role="tab" と aria-selected を付けて終わることがよくあります。これは修正になりません。スクリーンリーダーは「タブ」と読むようになりますが、Tabキーで移動もキーで開くこともできないため、使えない操作要素の存在だけを伝えることになります。表示中のパネルだけを描画する修正もよく見られますが、ほかのタブの aria-controls が存在しないidを指したままになります。すべてのタブでTab、矢印キー、Enterを押し、それぞれの読み上げを聞いて確かめてください。
試してみる
キーボードで「サイズ」のタブを開いてください。
Tabキーを押してから、矢印キー、Home、Endを試してください。下の欄に、スクリーンリーダーの読み上げが出ます。どのタブを表示中か分かりますか?
問題あり 修正できますか?
- 説明
- サイズ
- レビュー(12)
ワックスコットン、ウールの裏地付き。 お手入れ方法
スクリーンリーダーの読み上げ:
(Tabキーを押してください)再現デモです。「問題あり」は意図的にアクセシブルでない状態にしています。
修正方法
buttonの上にタブのパターンを作ります。Tabの移動先は一つ、矢印キーで移動し、表示中のタブにaria-selectedを付けます。
- 1タブのリストでのTabの移動先は一つにし、矢印キー、Home、Endでタブ間を移動する。
- 2表示中のタブに
aria-selected="true"を付け、見た目もその属性から設定する。 - 3ほかのパネルは
hiddenで隠し、ページからは消さない。
<ul class="tabs"> <li class="tab active" onclick="show('description')">説明</li> <li class="tab" onclick="show('sizes')">サイズ</li> <li class="tab" onclick="show('reviews')">レビュー(12)</li></ul><div class="panel" id="description"> <p>ワックスコットン、ウールの裏地付き。<a href="/care">お手入れ方法</a></p></div><div class="panel" id="sizes" style="display: none">…</div><div class="panel" id="reviews" style="display: none">…</div><div role="tablist" aria-label="商品の詳細"> <button type="button" role="tab" id="tab-description" aria-selected="true" aria-controls="panel-description">説明</button> <button type="button" role="tab" id="tab-sizes" aria-selected="false" aria-controls="panel-sizes" tabindex="-1">サイズ</button> <button type="button" role="tab" id="tab-reviews" aria-selected="false" aria-controls="panel-reviews" tabindex="-1">レビュー(12)</button></div><div role="tabpanel" id="panel-description" aria-labelledby="tab-description" tabindex="0"> <p>ワックスコットン、ウールの裏地付き。<a href="/care">お手入れ方法</a></p></div><div role="tabpanel" id="panel-sizes" aria-labelledby="tab-sizes" tabindex="0" hidden>…</div><div role="tabpanel" id="panel-reviews" aria-labelledby="tab-reviews" tabindex="0" hidden>…</div>この方法を選ぶ理由:クラスではなく状態から見た目を決める
リスト項目はTabキーの移動順に入らないため、キーボードでは「サイズ」も「レビュー」も開けません。active クラスは、選択中のタブを見た目だけで示しています。
タブのリストでのTabキーの移動先は、選択中のタブ一つだけです。矢印キーでタブ間を移動すると、そのタブのパネルが表示されます。HomeとEndで端のタブへ移動します。スクリーンリーダーは「サイズ、タブ、選択済み、2/3」のように読み上げます。すべてのパネルをページに残して隠すため、aria-controls は常に実在する要素を指し、隠れたパネルのリンクにはフォーカスが移りません。パネルは文章から始まるので tabindex="0" を付け、タブのリストの次のTabでパネル自体に移動するようにしています。選択中の見た目は aria-selected から設定するため、画面とコードで別のタブを示すことがありません。
テスト済みのタブのコンポーネントを使えば、これらはすべて任されます。多くの場合、手書きのスクリプトより安全です。ただし、使うコンポーネントが、タブのリストでのTabの移動先を一つにし、矢印キーで移動し、aria-selected を設定し、ほかのパネルを隠すかを確認してください。ボタンの並びをタブのように装飾するだけのライブラリもあります。パターンに沿っていても、次の点は決める必要があります。
- 自動か手動か:上のコードは、矢印キーでタブに移動した時点でパネルを表示します。パネルの読み込みに時間がかかる場合は、EnterかSpaceで表示し、矢印キーではフォーカスだけを移します。
- 縦のタブ:タブのリストに
aria-orientation="vertical"を付け、上下の矢印キーを使います。 - 必要なときだけ描画するパネル:フレームワークは選択中のパネルだけを描画しがちです。すべてのパネルを描画してほかは
hiddenで隠すか、aria-controlsを選択中のタブにだけ付けて、何も指さない状態をなくしてください。そうすれば自動チェックで報告されることもありません。 - 狭い画面:スマートフォンでタブをアコーディオンに変える場合は、レイアウトに合わせて役割も切り替えます。
role="tab"を縦に並べただけでは、タブとして読み上げられたままです。 - パネルのフォーカス:この例のパネルは文章から始まるため、
tabindex="0"を付けます。リンクや入力欄から始まるパネルでは、次のTabでその要素に移るため、tabindexは不要です。
タブごとに別のページを読み込む場合、それはタブではなくナビゲーションです。nav の中のリンクにして、現在のリンクには aria-current="page" を付けてください。強制カラーモードでも選択中のタブが分かるよう、背景色だけでなく線や太さで示してください。
AI コーディングアシスタントで修正しますか? このガイドを Markdown で取得
修正の確認
マウスを使わない5つの確認
確認方法: キーボード、スクリーンリーダー、ズーム、強制配色
OS、ブラウザーと支援技術のバージョン、ビルド、実施日、各手順の実際の結果を記録してください。共通のタブのコンポーネントを変更した際は、再度確認します。
制限
このサンプルは、どのアプリケーションでも同じ結果になることを保証するものではありません。スクリプトは最小限の例で、1ページに一つのタブのリストだけを扱い、ディープリンクや選択の保持はありません。タブとその位置の読み上げ方は、スクリーンリーダーによって異なります。対象の支援技術で、操作全体を確認してください。
よくある問題を再現した学習用のサンプルです。実在のクライアントの診断結果ではありません。コードは出発点となる実装例のため、実際の製品でも確認してください。ここでは支援技術でのテスト結果は報告していません。
コードを更新しても、使いやすさを保つために
ガイドの内容を、コーディングエージェントやCIで使える開発ルールにまとめます。更新後は、キーボードとスクリーンリーダーで再テストし、問題が再発していないか確認します。