名前がないアイコンだけのボタン
ヘッダーの検索、かご、メニューのボタンはSVGアイコンだけで言葉がなく、どれも「ボタン」としか読み上げられません。
問題
スクリーンリーダーや音声操作の利用者が、ヘッダーのボタンが何をするのか分かりません。
文具店のヘッダーは、左に店名、右に丸いボタンが3つ並んでいます。検索の虫眼鏡、小さな「2」のバッジが付いたかご、メニューの三本線です。画面が見えるマウス利用者はアイコンを見て押せます。スクリーンリーダー利用者がTabキーで移動すると、「ボタン」「2、ボタン」「ボタン」と読み上げられ、どれがメニューを開くのか分かりません。
各ボタンの中身は、スプライトを use で参照するSVGだけです。title も aria-label もないSVGは文字を持たないため、ボタンにアクセシブルな名前がありません。中にある文字はバッジの「2」だけです。WCAG 4.1.2 はすべての操作要素にプログラムで判別できる名前を求め、1.1.1 はアイコンの意味をテキストで提供することを求めています。
スクリーンリーダー利用者には役割しか伝わらず、一つずつ押して確かめるしかありません。フォーム部品の一覧でも、3つの項目を区別できません。音声操作の利用者はボタンの名前を言って押しますが、名前がないと番号を表示する遅い方法に頼ることになります。三本線がメニューだと知らない人にも、言葉は役に立ちます。
axe の button-name は名前のないボタンを確実に検出します。ただし名前の中身は判断しないため、aria-label="icon" や「虫眼鏡」、スプライトのファイル名でも合格になります。AIによる手早い修正では、操作ではなく絵に名前を付けたり、SVGに aria-label を付けてボタンは空のままにしたり、かごを「かご」としながら見えるバッジの「2」が余分に読まれたりします。名前が意味をなすかは、人が確かめる必要があります。
試してみる
Tabキーでヘッダーのボタンを順に移動してください。
下の欄に、スクリーンリーダーの読み上げが出ます。どのボタンがメニューを開くか分かりますか?
スクリーンリーダーの読み上げ: (Tabでボタンへ移動)
再現デモです。「問題あり」は意図的にアクセシブルでない状態にしています。
修正方法
アイコンボタンに言葉の名前を付けます。隠したテキスト、aria-label、見えるラベルのいずれかを使います。
- 1すべてのアイコンボタンに、隠したテキスト、aria-label、見えるラベルのいずれかで言葉の名前を付ける。
- 2アイコン自体は aria-hidden="true" で隠す。
- 3絵ではなく操作や行き先を名前にし、件数は一度だけ読ませる。
<header class="site-header"> <a href="/" class="logo">Fern & Fold</a> <button type="button" class="icon-button"> <svg class="icon"><use href="#icon-search"></use></svg> </button> <button type="button" class="icon-button"> <svg class="icon"><use href="#icon-bag"></use></svg> <span class="badge">2</span> </button> <button type="button" class="icon-button"> <svg class="icon"><use href="#icon-menu"></use></svg> </button></header>SVGはボタンに文字を与えないため、検索とメニューのボタンには名前がなく、かごの名前は「2」になります。3つとも、ボタンであること以外は伝わりません。
言葉はページ内の実際のテキストなので、「検索、ボタン」「かご、2点、ボタン」「メニュー、ボタン」と読み上げられ、ブラウザーの翻訳でも訳されます。隠したテキストに件数が含まれるため、バッジは隠します。隠さないと、件数が2回読まれます。
三つとも各ボタンに名前を付け、4.1.2と1.1.1を満たします。隠したテキストはデザインを変えず、ページと一緒に翻訳されるため、言葉を置く余白のないヘッダーに向いています。aria-label もデザインを変えず、コンポーネントでは最も簡単ですが、ブラウザーの翻訳機能によっては元の言語のまま残ります。見えるラベルは場所を取りますが、アイコンが分からない人にも役立つのはこの方法だけです。レイアウトが許す場所では見えるラベルを選び、許さない場所では他の二つのどちらかを使います。
絵ではなく操作を名前にする。 「検索」「閉じる」「メニュー」は何が起きるかを示します。「虫眼鏡」「バツ」「ハンバーガー」は絵の説明で、「icon-bag.svg」のようなファイル名は何も伝えません。お気に入りのハートのような切り替えボタンは、名前を変えずに aria-pressed で状態を示します。
アイコンは必ず隠す。 aria-hidden="true" がないと、名前のないSVGを「画像」や「グループ」と読むスクリーンリーダーがあり、アイコンフォントは私用領域の文字を読み上げることがあります。名前のあるボタン内のSVGに title があると、組み合わせによっては二重に読まれます。
ツールチップは名前ではない。 title 属性やホバーで出るツールチップは名前の代わりに使われることがありますが、一貫せず、タッチやキーボードでは表示されないブラウザーもあります。ボタンに直接名前を付け、ツールチップを使う場合は名前と同じ言葉にします。
コンポーネント。 共通のアイコンボタンでは名前を必須のプロパティにし、名前のないボタンを作れないようにします。任意にすると、いずれ省かれます。
件数や状態の変化。 かごの件数が変わったら、バッジだけでなく名前も更新します。変化を伝える必要がある場合は、ステータス領域で知らせます。ボタンの名前を変えただけでは読み上げられません。
修正の確認
マウスを使わない4つの確認
確認方法: キーボード、スクリーンリーダー、ズーム、強制配色
OS、ブラウザーと支援技術のバージョン、ビルド、実施日、各手順の実際の結果を記録してください。共通のアイコンボタンのコンポーネントを変更した際は、再度確認します。
制限
このサンプルは、どのアプリケーションでも同じ結果になることを保証するものではありません。コード内のスプライトのidとクラス名は仮のものです。後からコンテンツの編集者や外部のウィジェットが追加するアイコンボタンも、同じように確認が必要です。実際に使用する支援技術で、操作全体を確認してください。
よくある問題を再現した学習用のサンプルです。実在のクライアントの診断結果ではありません。コードは出発点となる実装例のため、実際の製品でも確認してください。ここでは支援技術でのテスト結果は報告していません。
コードを更新しても、使いやすさを保つために
ガイドの内容を、コーディングエージェントやCIで使える開発ルールにまとめます。更新後は、キーボードとスクリーンリーダーで再テストし、問題が再発していないか確認します。