トピックを検索
読み上げられない、divやspanのaria-label
商品一覧が星の評価と送料無料のアイコンを aria-label 付きの span に入れていますが、ロールのない span には名前を付けられないため、多くのスクリーンリーダーは評価の場所で何も読みません。
<span class="icon-truck" aria-label="送料無料"> 問題
スクリーンリーダー利用者が、商品の評価や送料が無料かどうかを知ることができません。
ショップの一覧ページに、商品が2件カードで並んでいます。各カードには見出しとして商品名があり、5つの星のうちいくつかが塗られ、片方のカードには送料無料を表す小さなトラックのアイコンがあります。見える人は、エプロンの評価が5点中4点で送料無料、トートが3点だと一目で分かります。あるスクリーンリーダーは閲覧モードで「リネンのエプロン、見出しレベル3」「キャンバスのトート、見出しレベル3」と読み、その間は何も読みません。同じページで「5点中4点の評価、送料無料」と読むスクリーンリーダーもあります。開発者は後者で確認したため、ページは完成しているように見えました。
星とトラックはCSSで描かれていて、それを入れる要素の中身は空です。言葉を与えるため、それぞれに aria-label が付いています。<span class="stars" aria-label="5点中4点の評価"> と <span class="icon-truck" aria-label="送料無料"> です。ロールのない span のロールは generic で、ARIAはこのロールに名前を付けることを禁止しています。名前を付ける対象(操作要素、画像、領域)ではないため、ブラウザーやスクリーンリーダーはラベルを無視してよく、よく使われるスクリーンリーダーのいくつかは閲覧モードで実際に無視します。そのため、評価と送料の条件には支援技術に確実に届く代替テキストがなく、1.1.1を満たしません。axe はこの属性を4.1.2として報告します。付けたはずの名前が伝わらないためです。
この問題は、スクリーンリーダーとその使い方によって現れ方が変わります。あるモードではラベルを読み、別のモードでは飛ばすこともあります。だからこそ見落とされやすいのです。開発者がたまたま使うスクリーンリーダーでしか動かないページは、動いているとは言えません。
10グループ中2グループに影響
- 全盲 (影響あり)
- 弱視 (影響なし)
- 色覚 (影響なし)
- ろう (影響なし)
- 難聴 (影響なし)
- 発話 (影響なし)
- 手の操作 (影響なし)
- 届く範囲・力 (影響なし)
- 認知 (影響あり)
- 光過敏 (影響なし)
- 視覚を使わない スクリーンリーダー利用者には各商品の名前しか聞こえず、評価を比べることも、送料無料の商品を探すこともできません。ラベルを読むスクリーンリーダーもあるため、同じページで聞こえる内容が人によって違います。
- 言語・認知・学習の能力が限られる 小さなトラックが送料無料を表すと知らない人は、条件が言葉で書かれていないと、アイコンだけを頼りにするしかありません。
axe の aria-prohibited-attr は、ロールのない div や span の aria-label を検出するため、属性は見つかります。それでも、1種類のスクリーンリーダーで確かめるとラベルが読まれるため、結果を無視するチームが多くあります。また、言葉が重要かどうかは自動チェックには分かりません。見えるテキストを繰り返すだけの aria-label は無害な余分ですが、評価を伝える aria-label は失われる情報です。AIによる手早い修正では、ラベルのある要素に一律に role="img" を付けがちで、テキストやリンクを含む要素ではそれらが画像の中に消えます。ラベルを title 属性に移す修正もよくありますが、多くのスクリーンリーダーはそれも読みません。各ラベルが必要な情報を運んでいるか、修正後に届いているかは、人が確認する必要があります。
試してみる
カードと、スクリーンリーダーの読み上げを比べてください。
下の欄に、span のラベルを読まないスクリーンリーダーの読み上げが出ます。各商品の評価と、どちらが送料無料か分かりますか?
問題あり 修正できますか?
リネンのエプロン
キャンバスのトート
ラベルを読まないスクリーンリーダーの読み上げ:
- リスト、2項目
- リネンのエプロン、見出しレベル3
- キャンバスのトート、見出しレベル3
再現デモです。「問題あり」は意図的にアクセシブルでない状態にしています。
修正方法
ラベルは、名前を持てる要素に付けるか、テキストとして中身に入れて、読まれる場所に置きます。
- 1aria-label は、名前を持てるロールの要素(操作要素、ランドマーク、画像、フレーム)にだけ付ける。
- 2画像には role="img" とラベルを付けるか、意味をテキストとして中身に入れる。
- 3意味を隣に書いたときは、画像そのものを aria-hidden="true" で隠す。
<ul class="products"> <li class="card"> <h3>リネンのエプロン</h3> <span class="stars stars-4" aria-label="5点中4点の評価"></span> <span class="icon-truck" aria-label="送料無料"></span> </li> <li class="card"> <h3>キャンバスのトート</h3> <span class="stars stars-3" aria-label="5点中3点の評価"></span> </li></ul>画像に名前を付けられるロールを与える
<ul class="products"> <li class="card"> <h3>リネンのエプロン</h3> <span class="stars stars-4" role="img" aria-label="5点中4点の評価"></span> <span class="icon-truck" role="img" aria-label="送料無料"></span> </li> <li class="card"> <h3>キャンバスのトート</h3> <span class="stars stars-3" role="img" aria-label="5点中3点の評価"></span> </li></ul>星とトラックは CSS の背景画像なので、各 span の中身は空です。
span は空でロールがないため、ラベルが読まれないことがあり、多くのスクリーンリーダー利用者には評価と送料の条件が届きません。
role="img" で各 span は一つの画像になり、画像には名前を付けられるため、スクリーンリーダーは「5点中4点の評価、画像」「送料無料、画像」と読みます。各要素に属性を一つ足すだけの、最も小さな変更です。ただし、span の中身が画像だけだから成り立ちます。role="img" は中身をすべて隠すため、テキストやリンクを含む要素には付けないでください。言葉は支援技術にしか届かず、トラックの意味を知らない見える人には何も伝わらないままです。
どの方法でも、評価と送料の条件がスクリーンリーダーに読まれる場所に置かれるため、1.1.1を満たします。role="img" は最も小さな変更ですが、言葉は支援技術にしか届かず、aria-label を翻訳しない翻訳ツールもあります。隠したテキストはどのスクリーンリーダーでも読まれ、翻訳もされますが、見える人にはアイコンしか残りません。カードに言葉を書く方法は普通のHTMLで済み、ページを読むすべての人に届き、ARIAに任せるものが残りません。こちらを使ってください。言葉を置く余白が本当にない場所に限り他の二つを使い、その場合はロールが不要で翻訳される、隠したテキストを選びます。
名前を持てる要素。 aria-label が働くのは、名前を付けられるロールの要素です。ボタン、リンク、入力欄などの操作要素、nav などのランドマーク、画像、iframe、ダイアログ、表、グループがそうです。ARIAは、次のようなロールに名前を付けることを禁止しています。
generic。ほかのロールのないdivとspanのロールです。paragraph。pのロールです。presentationとnone。要素のロールを意図的に取り除きます。strong、emphasis、code、time、mark、deletion、insertion、subscript、superscript、term、definitionなどの文字レベルのロールと、caption。
aria-labelledby も同じロールでは禁止されているため、隠したテキストを指しても解決しません。
読み方を変えたいテキスト。 <time aria-label="2026年10月3日">10/3</time> や <span aria-label="12点">12</span> のように、テキストの読み方を変えるためにラベルを付けることがよくあります。どちらの要素にも名前は付けられません。詳しい言葉を見えるテキストで書くか、短い表記の隣に視覚的に隠したテキストを置き、短い表記を aria-hidden="true" で隠します。スクリーンリーダーは短い日付や数字をすでにうまく読むため、変更が本当に必要か先に確認してください。
title や aria-describedby は代わりにならない。 title 属性は、一部のスクリーンリーダーが一部の要素でだけ読み、画面上はマウスを乗せたときにしか表示されません。aria-describedby はどの要素にも付けられますが、スクリーンリーダーが説明を読むのは主に操作要素にフォーカスが移ったときで、span の説明は聞き逃されやすくなります。
role="img" は中身を隠す。 role="img" の要素の中身は、すべて画像の一部として扱われ、読まれません。画像だけを持つ要素にだけ使い、件数やリンクは外に置きます。
コンポーネントのprops。 label を受け取り、外側の div に aria-label として渡すコンポーネントは多くあります。実際に出力されるHTMLを確認してください。ロールのない囲みのラベルは失われます。共通のアイコンや評価のコンポーネントでは、ラベルを受け取ったら role="img" を付けるか、ラベルを隠したテキストとして出力します。
AI コーディングアシスタントで修正しますか? このガイドを Markdown で取得
修正の確認
マウスを使わない4つの確認
確認方法: スクリーンリーダー
OS、ブラウザーと支援技術のバージョン、ビルド、実施日、各手順の実際の結果を記録してください。ラベルを出力する共通コンポーネントを変更した際は、再度確認します。
制限
このサンプルは、どのアプリケーションでも同じ結果になることを保証するものではありません。クラス名は仮のもので、星とトラックはCSSやアイコンフォントで描くあらゆる画像の例です。禁止された名前の扱いはスクリーンリーダーのバージョンによって変わり、あるモードでは読み別のモードでは読まないものもあるため、1種類のスクリーンリーダーで問題がなくても、ほとんど何も証明しません。ラベルが必要な情報を運んでいるのか、見えるテキストを繰り返しているだけなのかはページによって違い、人が判断する必要があります。実際に使用する支援技術で、操作全体を確認してください。
よくある問題を再現した学習用のサンプルです。実在のクライアントの診断結果ではありません。コードは出発点となる実装例のため、実際の製品でも確認してください。ここでは支援技術でのテスト結果は報告していません。
コードを更新しても、使いやすさを保つために
ガイドの内容を、コーディングエージェントやCIで使える開発ルールにまとめます。更新後は、キーボードとスクリーンリーダーで再テストし、問題が再発していないか確認します。