トピックを検索
表示と名前が食い違うボタンとリンク
ショップが「かごに入れる」ボタンそれぞれに、商品名と「カート」を含む aria-label を付けたため、名前にボタン上の言葉が含まれず、音声操作でボタンを見つけられません。
aria-label="Linen toteをカートに追加" 問題
音声操作の利用者は、見えている言葉を話してもショップの「かごに入れる」ボタンを押せず、スクリーンリーダー利用者は画面と違う言葉を聞きます。
生活雑貨のショップが、商品を一覧で並べています。各カードには写真、商品名、価格、濃い色の「かごに入れる」ボタンがあります。開発者はボタンの名前がすべて同じだと気づき、それぞれに商品名を入れた aria-label「Linen toteをカートに追加」を付けました。スクリーンリーダーのボタン一覧では分かりやすくなります。ところが音声操作の利用者がカードを見て「かごに入れるをクリック」と話しても、何も起きません。その名前のボタンがページにないからです。スクリーンリーダー利用者には「Linen toteをカートに追加、ボタン」と聞こえますが、ページやヘルプの文は「かご」と書いています。
aria-label はボタン自身のテキストに代わってアクセシブルな名前になるため、ボタン上の「かごに入れる」は名前にまったく含まれません。WCAG 2.5.3「ラベルを含む名前」(レベルA)は、見えるテキストのラベルがある操作要素の名前に、そのテキストが含まれることを求めています。見えている言葉を話して操作できるようにするためです。名前には表示どおりの言葉が含まれている必要があり、大文字小文字やほとんどの句読点は問いません。WCAGの解説書(Understanding)は、名前がその言葉で始まるのが望ましい実践だとしています。
同じ問題は、次の形でも起きます。
- カードの見出しだけを指す
aria-labelledby。名前が「Linen tote」になり、「かごに入れる」が抜けます。 - 表示の言葉を
aria-hidden="true"で包み、「Linen toteをカートに追加」のような別の言葉を視覚的に隠して入れる形。 - 「かご (2)」と表示し、
aria-label="ショッピングカート"を付けた、アイコンと文字のリンク。
「Linen tote、かごに入れる」のように、言葉を含んでいても先頭にない名前は2.5.3を満たしますが、望ましい形ではありません。「かごにLinen toteを入れる」のように表示の言葉の間に隠した言葉を挟むと、言葉は残っても一続きではなくなります。解説書はこれを将来の不適合の候補として挙げているだけですが、失敗例F96はすでにこの形を例に挙げています。画面の言葉が、一続きの文字列として名前に含まれないからです。不適合として扱ってください。
aria-label は助けるつもりで付けられ、スクリーンリーダーのボタン一覧では実際に役立ちます。各商品が別々の項目になるからです。それ以外の場面では、聞こえる言葉と見える言葉を食い違わせます。
10グループ中3グループに影響
- 全盲 (影響あり)
- 弱視 (影響なし)
- 色覚 (影響なし)
- ろう (影響なし)
- 難聴 (影響なし)
- 発話 (影響なし)
- 手の操作 (影響あり)
- 届く範囲・力 (影響なし)
- 認知 (影響あり)
- 光過敏 (影響なし)
- 手の操作が限られる 音声操作の利用者は、ボタン上の言葉を話して押します。名前が「カート」なので「かごに入れるをクリック」は何にも一致せず、番号やグリッドの表示に頼ることになり、商品ごとに何度も話す必要があります。
- 視覚を使わない スクリーンリーダー利用者には「Linen toteをカートに追加」と聞こえますが、ページやヘルプ、案内する人は「かごに入れる」と言うため、伝えられた言葉でボタンにたどり着けません。
- 言語・認知・学習の能力が限られる 読むのを助けるためにスクリーンリーダーや読み上げ機能を使う、画面が見える人は、画面の「かご」と違う「カート」を聞き、同じボタンだと自分で結び付ける必要があります。
axe にはこの問題を調べる label-content-name-mismatch ルールがありますが、試験的なルールのため、指定したときだけ実行されます。この診断ではこのルールを実行し、見つかったものを人が確かめる要確認項目として報告します。このルールは aria-label や aria-labelledby を表示テキストと比べるため、修正前の例、見出しだけを指す aria-labelledby、アイコンのリンクは検出できます。ただし、中身の隠したテキストで名前が付いたボタンや、<input type="submit" value="検索" aria-label="商品を探す"> のような入力ボタンは調べません。この診断独自のチェックが、画面に描かれた言葉とブラウザーが算出した名前を比べて、それらを検出します。「ボタンの名前がすべて同じ」という指摘へのAIの手早い修正は、修正前の例そのものになることがあります。ボタンごとに、モデルが選んだ言葉の aria-label を付けてしまいます。
試してみる
再現した音声操作で「かごに入れるをクリック」と話してから、Tabキーで各ボタンへ移動してください。
音声操作は、話した言葉を名前に含むボタンを探します。商品の下に、スクリーンリーダーが読み上げる名前が出ます。
問題あり 修正できますか?
Linen tote
$48
Enamel mug
$18
スクリーンリーダーの読み上げ:
(Tabでボタンへ移動)
修正方法
各ボタンの名前を表示されている言葉で始め、商品名はその後ろか説明に入れます。
- 1ボタンやリンクの名前は、表示されている言葉を含み、その言葉で始める。
- 2補足は表示の言葉の後ろか説明として足し、表示の言葉と置き換えない。
- 3表示の言葉を aria-hidden で隠して、別の言葉で名前を付けない。
<ul class="products"> <li class="card"> <img src="linen-tote.jpg" alt=""> <h3>Linen tote</h3> <p class="price">$48</p> <button type="button" aria-label="Linen toteをカートに追加">かごに入れる</button> </li> …</ul>ボタン自身の言葉にし、商品名を説明にする
<ul class="products"> <li class="card"> <img src="linen-tote.jpg" alt=""> <h3 id="product-linen-tote">Linen tote</h3> <p class="price">$48</p> <button type="button" aria-describedby="product-linen-tote">かごに入れる</button> </li> …</ul>ボタンには「かごに入れる」と表示されていますが、名前は「Linen toteをカートに追加」です。表示の言葉が名前にないため、「かごに入れるをクリック」はどこにも届きません。
aria-label を外すと、ボタンのテキストが再び名前「かごに入れる」になります。見出しは説明になり、スクリーンリーダーは名前と役割の後に読み上げます。「かごに入れる、ボタン、Linen tote」です。「かごに入れるをクリック」はどのカードのボタンにも一致するため、音声操作は繰り返しのラベルのときと同じように番号を付け、利用者はどれかを選べます。
どちらも名前を表示の言葉で始め、2.5.3を満たします。説明を使う方法は、名前を表示の言葉そのままに保ち、カードの見出しがボタンのすぐそばにある一覧に向いています。ただし説明はスクリーンリーダーのボタン一覧には出ず、一覧ではどの項目も「かごに入れる」のままです。説明の読み上げを切っている人もいます。隠したテキストは商品名を名前そのものに入れるため、どこに一覧されても各ボタンを区別できます。代わりにボタンごとに隠した span が1つ要ります。同じボタンがページに何度も並ぶときは隠したテキストを、はっきりした見出しのそばに数個並ぶだけなら説明を選びます。音声認識ソフトの違いもあります。DragonとWindowsの音声アクセスは名前の一部でも照合しますが、Appleの音声コントロールは名前全体が必要だと報告されています。隠したテキストの方法では、MacやiPhoneで「かごに入れるをクリック」と話してもボタンに届かず、番号に頼ることになるかもしれません。利用者の多くがApple製品を使うなら、ボタン一覧が短くなる利点と比べて選んでください。
aria-labelかaria-describedbyか。 この二つは役割が違います。aria-label(と aria-labelledby)は名前を決めます。音声操作が照合し、スクリーンリーダーが最初に読み、ボタン一覧に表示するのが名前です。ボタンの文字は、この名前に置き換わります。aria-describedby は名前を変えずに説明を足し、説明は名前と役割の後に読まれます。音声操作は説明では照合せず、説明の読み上げを切っている人もいます。そのため、どちらを使うかは、操作要素に何が表示されているかで決まります。
- 言葉が表示されている:その言葉が名前なので、
aria-labelは付けません。どの商品か、補足の説明などは、説明にするか、名前の中で言葉の後ろに足します。 - アイコンだけが表示されている:残す言葉がないため、
aria-labelで名前を付けます。 - 言葉が表示されている操作要素の
aria-labelが安全なのは、その言葉で始まる場合だけです。その場合も、言葉の後ろに隠したテキストを置けば、ARIAなしで同じことができます。
足す言葉は、ARIAよりHTMLで。 ボタン自身の id を先に、見出しの id を後に並べた aria-labelledby="add-linen-tote product-linen-tote" でも、隠したテキストと同じ名前「かごに入れる Linen tote」になります。ボタン内に span を入れられないコンポーネントでは、こちらが使えます。隠したテキストはidが要りません。どちらもページ上のテキストなので、ページと一緒に翻訳されます。マークアップに書いた aria-label はそうとは限らず、ブラウザーの翻訳機能によっては元の言語のまま残り、食い違いが戻ることがあります。
表示の言葉を先頭に、一続きで。 足す言葉は表示の言葉の後ろに置き、前や間には入れません。「Linen tote、かごに入れる」は適合しますが、見えている言葉で始まりません。「かごにLinen toteを入れる」は、利用者が話す言葉を分断します。
言葉を言い換えない。 「カート」と「かご」、「購入」と「注文」、「ログイン」と「サインイン」は、開発者には同じでも、音声認識には別の言葉です。名前にもヘルプの文にも、画面に出ている言葉を使います。
アイコンと記号。 アイコンだけのボタンには見える言葉がないため、2.5.3の対象外です。言葉の名前が必要なことは、名前がないアイコンだけのボタンで扱っています。「次へ」の後ろの矢印のように、言葉に添えた記号はラベルの一部ではないため、名前は「次へ」で足ります。
フォームの入力欄。 同じ達成基準は入力欄のラベルにも当てはまります。入力欄の上に表示したラベルと違う aria-label は、ラベルがない・表示と食い違うフォームの入力欄で扱っています。
AI コーディングアシスタントで修正しますか? このガイドを Markdown で取得、または全ガイドをコーディングエージェントで使う。
修正の確認
マウスを使わない4つの確認
確認方法: 音声入力、スクリーンリーダー、キーボード
OS、ブラウザーと支援技術のバージョン、ビルド、実施日、各手順の実際の結果を記録してください。共通のボタンや商品カードのコンポーネントを変更した際は、再度確認します。
制限
このサンプルは、どのアプリケーションでも同じ結果になることを保証するものではありません。音声認識ソフトによって、話した言葉の照合方法は異なるため、利用者が使う音声操作で確認してください。外部のウィジェットやコンテンツの編集者が追加するボタンも、同じように確認が必要です。表示の言葉で始まる名前が、商品について十分に伝えているかは別の問題です。リンクについてはリンクテキストが空、または「詳しくはこちら」だけのリンクで扱っています。実際に使用する支援技術で、操作全体を確認してください。
よくある問題を再現した学習用のサンプルです。実在のクライアントの診断結果ではありません。コードは出発点となる実装例のため、実際の製品でも確認してください。ここでは支援技術でのテスト結果は報告していません。
コードを更新しても、使いやすさを保つために
ガイドの内容を、コーディングエージェントやCIで使える開発ルールにまとめます。更新後は、キーボードとスクリーンリーダーで再テストし、問題が再発していないか確認します。