WCAG 達成基準 · Level AAA
WCAG 2.4.9: リンクの目的(リンクのみ)
WCAG 2.4.9 では、周囲の文脈に頼ることなく、リンクテキストだけからすべてのリンクの目的が判断できることが求められています。このより厳格な AAA 基準により、すべてのユーザー、特にリンク単位で移動するスクリーンリーダー利用者が、ページ全体を読まなくてもリンク先を理解できるようになります。
- Level AAA
このルールの意味
\nWCAG 2.4.9 — Link Purpose (Link Only) は、WCAG 2.1 および 2.2 におけるレベル AAA の達成基準です。各リンクの目的がリンクテキスト単体から判断できることを求めています。見出し、段落、表セルなどの周囲の文脈からリンクの目的を推測することを認める AA レベルの対応基準 WCAG 2.4.4(Link Purpose — In Context)とは異なり、2.4.9 ははるかに厳格です。リンクテキスト自体が完全に自己説明的でなければならず、周囲のコンテンツに一切依存してはなりません。
\nこの基準は、<a> 要素で作成されたすべてのハイパーリンクに加え、アクセシブルネームを持ちリンクとして振る舞うあらゆるインタラクティブ要素に適用されます。これには、画像リンク(画像の alt 属性や aria-label がアクセシブルネームを提供する場合)、ボタン風のリンク、SVG ベースのリンクが含まれます。リンクのアクセシブルネームは、可視テキスト、aria-label、aria-labelledby、または画像の代替テキストから算出されますが、そのネーム単体でリンク先やリンクの機能を伝えなければなりません。
合格とみなされるもの: ユーザーがリンクテキストだけを読み、ページ上の他の何も読まなくても、そのリンクの遷移先や機能を自信を持って理解できる場合、そのリンクは 2.4.9 に合格します。たとえば、「Download the 2024 Annual Accessibility Report (PDF, 2.4 MB)」というリンクは、必要な情報がすべてリンクテキスト内に含まれているため合格です。「Read the full article: How to Write Accessible Link Text」というリンクも合格です。alt='View pricing plans' を持つ画像リンクも、alt テキストが十分に説明的であるため合格です。
不合格とみなされるもの: 「click here」「read more」「learn more」「this」「here」など、文脈がなければ意味をなさないフレーズをテキストとするリンクは、この基準に不合格となります。同様に、alt 属性が空または存在しない画像を囲むリンクで、リンクにアクセシブルネームがない場合も不合格です。aria-label や aria-labelledby を使用していても、算出されたアクセシブルネームが依然として曖昧な場合も不合格です。
公式の例外: WCAG は 1 つの例外を明示しています — リンクの目的が、障害の有無にかかわらず、すべてのユーザーに対して意図的に曖昧である場合です。たとえば、ミステリーゲームのティーザーリンクとして「Proceed」と表示され、曖昧さが意図されたデザインである場合、その曖昧さがすべてのユーザーに等しく適用されるのであれば、不合格とはみなされません。この例外は範囲が非常に狭く、不適切なリンクテキストを正当化する抜け道として使うべきではありません。
\n\nなぜ重要か
\n意味のあるリンクテキストは、ウェブサイトが行えるアクセシビリティ改善の中でも最も影響力の大きいものの 1 つです。曖昧なリンクテキストの影響を最も直接受けるのは、スクリーンリーダー利用者、キーボードでナビゲーションするユーザー、認知障害のあるユーザー、音声コントロールソフトウェアの利用者です。
\nスクリーンリーダー利用者 — 一般的には全盲または重度のロービジョンの人々 — は、ページ上のすべてのリンクの一覧を呼び出してページを移動することがよくあります。NVDA、JAWS、VoiceOver などの一般的なスクリーンリーダーはすべてこの機能を提供しており、各リンクのアクセシブルネームを抽出して独立したリストとして提示します。リンクが「click here」「read more」「details」といった文言である場合、このリストは同一で意味のない項目の羅列になってしまいます。ユーザーは、各リンクの周囲のコンテンツを読まない限り、どのリンクを起動すべきか判断できません。これは、特にリンクが多数あるページでは、遅く、ストレスが大きく、ときには不可能な作業になります。
\n世界保健機関によると、世界で約 22 億人が何らかの視覚障害を抱えており、そのうち少なくとも 10 億人は予防可能であったか、まだ対処されていない状態にあります。視覚障害のないユーザーであっても、スイッチアクセスや音声ナビゲーション(Dragon NaturallySpeaking のようなツールを使用)に依存する運動障害のあるユーザーは、説明的なリンクテキストから大きな恩恵を受けます。リンクの名前をそのまま話したり選択したりしてリンクを起動できるからです。注意欠如、記憶障害、読字困難などを含む認知障害のあるユーザーも、明確なリンクラベルによって認知負荷や文脈を読み返す必要が減るため、恩恵を受けます。
\n現実のシナリオを考えてみましょう。トルコの市民が、公立病院のウェブサイトで予約を取るためにアクセスしているとします。ページには 3 つのサービスボタンがあり、それぞれのリンクテキストには「Randevu Al」(予約を取る)というフレーズだけが含まれています。スクリーンリーダーを起動した全盲のユーザーがリンクリストを開くと、「Randevu Al」「Randevu Al」「Randevu Al」と、区別のつかない 3 つの選択肢が表示されます。どのリンクが循環器科、どのリンクが一般診療、どのリンクが放射線科なのか、文脈に戻って確認しない限り判断できません。WCAG 2.4.9 を満たすには、それぞれのリンクが「Randevu Al — Kardiyoloji」「Randevu Al — Genel Pratisyen」「Randevu Al — Radyoloji」と表示され、リンクテキストだけで目的が明確になる必要があります。
\nアクセシビリティにとどまらず、説明的なリンクテキストには重要な SEO 上の価値もあります。検索エンジンクローラーはページをインデックスする際にアンカーテキストに重み付けを行い、説明的なリンクはリンク元ページとリンク先ページの両方に対する関連性シグナルを高めます。汎用的なアンカーテキストを意味のあるフレーズに置き換えることで、発見性が向上し、直帰率が低下し、すべてのユーザーにとって利便性が高まります。
\n\n関連する Axe-core のルール
\nWCAG 2.4.9 には手動テストが必要です。自動ツールは意味や意図を判断できず、アクセシブルネームの欠如を検出することはできても、与えられたアクセシブルネームが十分に説明的かどうかを判断することはできないからです。
\n- \n
- 手動テストが必要 — link-name(axe ルール): axe-core の
link-nameルールは、アクセシブルネームをまったく持たないリンク(たとえば、テキストコンテンツもaria-labelもaria-labelledbyもなく、非空のalt属性を持つ画像も含まない<a>要素)を検出します。このルールは完全に空のリンクを検出できますが、既に存在するアクセシブルネームが意味のあるものかどうかを評価することはできません。「here」と表示されるリンクは、技術的にはアクセシブルネームを持っているため、自動のlink-nameルールには合格しますが、そのネームが自己説明的ではないため WCAG 2.4.9 には不合格です。これこそが 2.4.9 が手動レビューを要するとされる理由です。人間が各リンクラベルを読み、そのラベル単体で目的を伝えているかどうかを判断する必要があります。 \n - 手動テストが必要 — identical-links-same-purpose: Axe-core には、アクセシブルネームが同一でありながらリンク先が異なるリンクの集合を検出するルールが含まれています。これは、複数の「Read More」リンクが異なる記事に向かっている場合など、2.4.9 違反の可能性を表面化させるヒューリスティックです。ただし、このルールでさえ人間による確認が必要です。同一の名前で同一のリンク先を指している場合は違反ではないからです。このルールはレビュー候補を挙げるものであり、確定的な不合格を示すものではありません。 \n
- 自動化だけでは不十分な理由: リンクの目的を評価するには自然言語の理解が必要です。自動ツールは、リンクのアクセシブルネームが「details」という文字列であることは計算できますが、その文字列が遷移先を説明できていないことまでは分かりません。同様に、「View」が十分かどうか(非常に限定されたインターフェースでは十分な場合もあります)や、「View the Q3 Financial Statement」の方が適切かどうかも判断できません。スクリーンリーダーテストを組み合わせた人間の判断こそが、唯一信頼できる方法です。 \n
テスト方法
\n- \n
- 自動スキャンによるベースライン: 対象ページで axe DevTools(ブラウザー拡張)または Lighthouse を実行します。axe DevTools では、
link-nameルールの違反がないか確認します。これらはアクセシブルネームをまったく持たないリンクを表し、2.4.9 の確実な不合格です。結果をエクスポートし、フラグされたすべてのリンクを記録します。このステップだけでは 2.4.9 の監査は完了しません。あくまで最も明白な不合格を特定する段階です。 \n - スクリーンリーダーでリンクリストを生成: NVDA をインストールした Firefox でページを開きます。Insert + F7(NVDA の要素リストショートカット)を押し、ダイアログから「Links」を選択します。リンクラベルの一覧をすべて確認します。「このリストだけを読むユーザーは、各リンクの遷移先や機能を理解できるか?」と自問してください。同じテストを JAWS でも行い、Insert + F7 を押して Links List ダイアログを開きます。macOS の Safari 上の VoiceOver では、VO + U を押してローターを開き、Links に移動します。ラベルが曖昧なリンク、異なる遷移先を持つのにラベルが重複しているリンク、URL 文字列だけで構成されているリンクをフラグします。 \n
- キーボードによるタブ移動監査: Tab キーだけを使ってページをナビゲートします。フォーカスがリンクに移動するたびに、フォーカスされた要素の可視テキストだけを読む(またはスクリーンリーダーの読み上げだけを聞く)ようにします。周囲のコンテンツを見ずに、そのリンクの目的が明確かどうか判断します。リンクテキストだけでは目的が不明瞭なリンクをすべて記録します。 \n
- 画像リンクの確認: 画像のみ(可視テキストなし)を含むリンクをすべて特定します。ブラウザーの開発者ツールでそれぞれを検査し、画像に空でない説明的な
alt属性があるか、またはリンクに説明的なaria-labelがあるかを確認します。アクセシブルネームの算出結果は意味のあるフレーズになっている必要があります。 \n - 重複リンクテキストの確認: ページの HTML を検索し、同じリンクテキストが複数回出現していないか確認します(たとえば、複数の「Read More」や「Buy Now」アンカー)。これらのリンクが同じ遷移先を指しているか(許容される)それとも異なる遷移先を指しているか(
aria-labelやaria-labelledbyで区別されていない限り 2.4.9 の不合格)を検証します。 \n - 音声コントロールテスト: Dragon NaturallySpeaking や Windows Voice Access を使用し、可視ラベルを発話してリンクを起動できるか試します。発話したラベルが曖昧で複数の候補が表示される場合(たとえば「Click Read More」と話すと複数のリンクがハイライトされる場合)、これは 2.4.9 に関連する実際のユーザビリティ上の問題があることを示します。 \n
修正方法
\n汎用的な「Read More」リンクテキスト — 不適切
\n<!-- Fails 2.4.9: link purpose cannot be determined from link text alone -->\n<article>\n <h3>How to Improve Your Website's Accessibility Score</h3>\n <p>Accessibility improvements can dramatically increase your user base...</p>\n <a href='/blog/improve-accessibility-score'>Read more</a>\n</article>\n汎用的な「Read More」リンクテキスト — 適切
\n<!-- Passes 2.4.9: link purpose is fully clear from link text alone -->\n<article>\n <h3>How to Improve Your Website's Accessibility Score</h3>\n <p>Accessibility improvements can dramatically increase your user base...</p>\n <a href='/blog/improve-accessibility-score'>\n Read more about improving your website's accessibility score\n </a>\n</article>\n\n<!-- Alternative: visually show short text but provide full accessible name -->\n<a href='/blog/improve-accessibility-score'\n aria-label='Read more about improving your website's accessibility score'>\n Read more\n</a>\n\nalt テキストが欠落した画像のみのリンク — 不適切
\n<!-- Fails 2.4.9: image link has no accessible name; screen readers announce URL or nothing -->\n<a href='https://accsible.com/pricing'>\n <img src='/icons/pricing.svg' alt=''>\n</a>\nalt テキストが欠落した画像のみのリンク — 適切
\n<!-- Passes 2.4.9: alt text gives the link a fully descriptive accessible name -->\n<a href='https://accsible.com/pricing'>\n <img src='/icons/pricing.svg' alt='View Accsible pricing plans'>\n</a>\n\n<!-- Alternative using aria-label on the anchor -->\n<a href='https://accsible.com/pricing' aria-label='View Accsible pricing plans'>\n <img src='/icons/pricing.svg' alt=''>\n <!-- alt='' hides decorative image from AT; aria-label on <a> provides the name -->\n</a>\n\n同一の「Satın Al」(今すぐ購入)リンクが複数存在 — 不適切
\n<!-- Fails 2.4.9: three identical link labels pointing to different products -->\n<div class='product-card'>\n <h3>Temel Plan</h3>\n <a href='/plans/basic'>Satın Al</a>\n</div>\n<div class='product-card'>\n <h3>Profesyonel Plan</h3>\n <a href='/plans/pro'>Satın Al</a>\n</div>\n<div class='product-card'>\n <h3>Kurumsal Plan</h3>\n <a href='/plans/enterprise'>Satın Al</a>\n</div>\n同一の「Satın Al」(今すぐ購入)リンクが複数存在 — 適切
\n<!-- Passes 2.4.9: each link has a unique, descriptive accessible name via aria-label -->\n<div class='product-card'>\n <h3>Temel Plan</h3>\n <a href='/plans/basic' aria-label='Temel Planı Satın Al'>Satın Al</a>\n</div>\n<div class='product-card'>\n <h3>Profesyonel Plan</h3>\n <a href='/plans/pro' aria-label='Profesyonel Planı Satın Al'>Satın Al</a>\n</div>\n<div class='product-card'>\n <h3>Kurumsal Plan</h3>\n <a href='/plans/enterprise' aria-label='Kurumsal Planı Satın Al'>Satın Al</a>\n</div>\n\n<!-- Alternative: use visually hidden text inside the anchor -->\n<a href='/plans/basic'>\n Satın Al <span class='sr-only'>— Temel Plan</span>\n</a>\n\n(Content truncated due to token limit — please retry this article.)
