シリーズ「アクセシビリティ通信」では、ウェブアクセシビリティに関するトピックを取り上げていきます。今回は「アクセシブルな名前(Accessible Name)」を中心に説明してきます。
アクセシブルな名前
見出し「アクセシブルな名前」リンクやボタンのように、フォーカス可能またはインタフラクティブな要素など、特定の要素は「アクセシブルな名前(Accessible Name)」を持ちます。この名前は、スクリーンリーダーや音声コントロールのような支援技術(Assistive Technologies、AT)のために使われます。
以下の HTML であれば、アクセシブルな名前は「メニュー」です。
この、アクセシブルな名前を調べる方法としては、各ブラウザのデベロッパーツールを使用するか、直接スクリーンリーダーを使用します。
以下は、Google Chrome のデベロッパーツールで先ほどの <button>
要素を調べたときのスクリーンショットです。
「Accessibility」ペインの確認方法は以下をご参照ください。
このアクセシブルな名前を持つ要素は、ロール(role)によって定められています。インタラクティブな要素以外でも、画像(image
)、表組み(table
)、領域(region
)、ダイアログ(dialog
)などのロールにおいてもアクセシブルな名前が求められます1。
ラベル(label)と名前(name)
見出し「ラベル(label)と名前(name)」WCAG において、「ラベル(label)」とは、ユーザ向けに提供されたテキストを指し、「名前(name)」とは、スクリーンリーダーなどの支援技術向けに提供されたマシンリーダブルなテキストを指します。
どちらも同一のテキストが指定されているケースが多いですが、このテキストに差異があるときに、アクセシビリティ上の問題が起こりやすくなります。
基本ルール
見出し「基本ルール」W3C が提供する Providing Accessible Names and Descriptions では、アクセシブルな名前や説明を指定するときの基本ルールがまとめられています。以下簡単に抜粋します。
1. ARIA の誤用に注意し、徹底的にテストする
見出し「1. ARIA の誤用に注意し、徹底的にテストする」ARIA 属性の誤用に注意することに加えて、何よりもテストすることが重要です。
100 万以上のホームページを対象とした WebAIM による調査の 2024 年版では、ARIA 属性の使用が増える一方で、ARIA が存在するページは存在しないページと比較して、平均 34.2% も多くエラーが検出されました2。ARIA の仕組み自体に問題があるということではなく、ARIA の誤用、もしくは不十分な実装によるアクセシビリティ上の問題が発生しやすいと考えられます。
以下の例は少し極端ですが、ARIA の間違った使い方によって、可視テキストの「メニュー」に対して、アクセシブルな名前は aria-label
属性で指定した「機能一覧」になります。
そのため、スクリーンリーダーでは「機能一覧、ボタン」のように異なるテキストが読み上げられます。このとき、ユーザに意味が通じていれば大きな支障はないかもしれませんが、音声コントロールでは問題がさらに深刻化します。
音声コントロールでは視覚的に表示されたラベルに対して「メニューをクリック」と発話しますが、この場合のアクセシブルな名前は「機能一覧」なのでボタンを選択することができません。
この問題は、WCAG 2.x の達成基準「2.5.3 ラベルを含む名前(name)」に該当し、特に aria-label
属性を使用する際には注意が必要です。
そして、このような誤用を未然に防ぐためにも、とりわけスクリーンリーダーを使用したテストを実施することが重要です。OS に標準搭載されているスクリーンリーダーの操作方法については、以下の過去記事で紹介しています。
2. 可視テキストを優先する
見出し「2. 可視テキストを優先する」aria-label
属性のような不可視テキストよりも、通常のテキストや <label>
要素のような可視テキストを優先します。可視テキストでは以下の優位性があります。
- メンテナンス性に優れている
- エラーを回避しやすくなる
- テストが容易になる
- コンテンツが認識しやすくなる
- 柔軟性や自由度が高くなる(機械翻訳、テキストのコピーなど)
例えば、アイコンの近くに可視テキストとしてのラベルが添えられることで役割がより明確になりますが、これは視覚に障害のあるユーザのみならず、すべてのユーザにとって恩恵があります。
状況によっては、aria-label
属性を使用したり、CSS による不可視テキストを使用しないと実現できないケースもあるかもしれませんが、まずは可視テキストを優先します。
3. ネイティブの技術を優先する
見出し「3. ネイティブの技術を優先する」このネイティブの技術とは、ウェブサイトにおいては HTML のことです。ARIA 属性を使用するよりも HTML の要素や属性を優先させます。
例えば、ボタンの機能を持つコンポーネントを実装するときに、<span>
のような汎用的な要素で擬似的に実現させるのでなく、最初から役割や機能が備わっている <button>
要素を使用します。
これは、アクセシビリティの確保に加えて、実装難易度やバグの回避、メンテナンス性など、さまざまな理由から優先すべき原則です。
4. ブラウザのフォールバックを避ける
見出し「4. ブラウザのフォールバックを避ける」title
属性と placeholder
属性は、<input>
要素などにアクセシブルな名前が見当たらないときに、そのフォールバックとして用いられます。
フォールバックが適用される条件については「優先順位」の項で説明します。
フォールバックな実装は、ブラウザの解釈が一定ではなく安定性が確保されません。
また title
属性の場合には入力デバイスによってテキストが表示できなかったり、placeholder
属性は入力すると消えてしまうといった問題もあるため、これらのフォールバックの指定は基本的には避けるべきです。
5. 簡潔で有用な名前を指定する
見出し「5. 簡潔で有用な名前を指定する」ユーザが目的を達成したり情報を取得しやすくすることを念頭に、アクセシブルな名前は簡潔で明瞭なテキストであることが望まれます。
具体的な方針をいくつかピックアップします。
機能や目的を伝える
見出し「機能や目的を伝える」特にインタラクティブな要素に含まれる場合、アクセシブルな名前にはその形状や位置などの視覚的な情報ではなく、機能や目的が伝わるテキストを指定します。
例えば、検索フォームのボタンに虫眼鏡の形をしたアイコンの画像を使用している例であれば、「検索」といったように、ボタンを選択したときの結果が予測しやすくなるようにします。
ただ、「2. 可視テキストを優先する」のルールを踏まえると、アイコン単体ではなく可視テキストのラベルを用意することが望ましいといえます。
ARIA ロールの内容を名前に含めない
見出し「ARIA ロールの内容を名前に含めない」スクリーンリーダーでは、アクセシブルな名前とともにロールが読み上げられます。そのため、重複して読み上げられないように名前にはロールの内容を含めないようにします。
例えば、button
ロールであれば、アクセシブルな名前に「ボタン」を含めるのは冗長です。
ページ内で名前が重複しないようにする
見出し「ページ内で名前が重複しないようにする」ページ内でアクセシブルな名前が重複している場合、スクリーンリーダーや音声コントロールによるブラウジングに支障をきたすため、可能な限りユニークな名前を付けるようにします。
よくあるケースとしては、文中の「こちら」のテキストリンクや、「詳しくはこちら」や「もっと見る」といったラベルが該当します。
例えば、スクリーンリーダーを使用して以下の HTML 内のリンクを順番に移動していくと、どれも「もっと見る、リンク」と読み上げられ、前後のテキストを確認しないと見分けがつきません。
aria-labelledby
属性で見出しと紐づける方法も考えられますが、マークアップが複雑になり、エラーの温床にもなるため推奨できません。
また、音声コントロールで「もっと見るをクリック」と発話した場合、画面内のどのリンクが選択されるのかが選択されるかの予測がつきません。
この問題は以下の記事でも取り上げましたが、コーディングの段階では対応が難しいことが多いので、設計・デザインの段階から意識することが求められます。
指定方法
見出し「指定方法」アクセシブルな名前を指定する方法は、ロールに応じていくつか存在します。
- 子孫要素のコンテンツを使用する
aria-label
属性を使用するaria-labelledby
属性を使用する- フォーム要素を
<label>
要素に紐づける - 特定の子要素を使用する
<fieldset>
要素に対する<legend>
要素<table>
要素に対する<caption>
要素<figure>
要素に対する<figcaption>
要素
title
属性やplaceholder
属性を使用する(フォールバック)
それでは、順番に見ていきましょう。
子孫要素のコンテンツを使用する
見出し「子孫要素のコンテンツを使用する」もっとも直感的なケースですが、要素に含まれる子孫要素のコンテンツがアクセシブルな名前として使用されます。以下の例では、アクセシブルな名前は「メニュー」です。
たとえ子孫要素の階層が深くなったとしても、そこに含まれるコンテンツが隠されていなければ名前として使用されます。
以下の例では、要素ごとの名前が半角スペースで結合され、最終的な名前は「アクセシビリティ 入門 (外部リンクを開く)」になります。
ただし、以下のケースでは、例外として子孫要素のコンテンツが名前から除外されます。
menuitem
ロールの下層に含まれるmenu
ロールのコンテンツtreeitem
ロールの下層に含まれるgroup
ロールのコンテンツ
除外されるのは親要素に対する子孫要素のコンテンツで、子孫要素自身の名前は除外されません。
aria-label
属性を使用する
この見出しのリンクaria-label
属性を使用して、アクセシブルな名前を指定する方法です。
以下の例では、 <nav>
要素に対して aria-label
属性を指定することで、「メイン、ナビゲーション」と読み上げられることを期待しています。
以下はすでに紹介したアンチパターンの例ですが、aria-label
属性を指定することで、アクセシブルな名前を上書きすることができます。
aria-label
属性は、基本ルールを守って控えめに使用しましょう。
aria-labelledby
属性を使用する
この見出しのリンクaria-labelledby
属性を使用して、アクセシブルな名前を指定する方法です。対象となる要素の id
属性と紐づけることで実現します。
なお、aria-labelledby
属性の値は、半角スペースで区切って id
の値を指定することで、複数のテキストを結合した名前を作成することができます。
以下の例では、「HTML の基本」と「記事を読む」を結合して「HTML の基本 記事を読む」という名前を作っています。
ここで注意する点としては、aria-labelledby
属性を指定した場合、aria-label
属性と同様に名前が上書きされるということです。
上記の例では「記事を読む」というリンクテキストの名前は、aria-labelledby
属性によって一旦上書きされますが、aria-labelledby="heading more"
と、見出しとリンクテキストの 2 つの id
を参照しているため「記事を読む」が再び名前として含まれることになります。
なお、aria-labelledby
が使用されるのは一度きりで、親要素を参照したとしても無限ループは発生しません。また、JS におけるプロトタイプチェーンのような連鎖も発生しません。
特筆すべき点として、aria-labelledby
属性では、参照先の要素が非表示でも名前として有効になります。これは後述する <label>
要素では実現不可能なことです。
しかし、この参照先を、以下のように隠されていない親要素に変更すると、今度はアクセシブルな名前が失われてしまいます。
この仕組みは複雑でトリッキーですが、そもそも aria-labelledby
属性の参照先は可視テキストを前提とすることで、この問題を避けることができます。
スクリーンリーダー向けのテキスト
見出し「スクリーンリーダー向けのテキスト」慣例的に .sr-only
や .visually-hidden
と命名される、スクリーンリーダー向けの不可視テキストを実装する CSS のテクニックがあります。
先ほどの aria-labelledby
属性の例を、.sr-only
で置き換えると以下のようなコードになります。この手法では子孫要素のコンテンツがアクセシブルな名前になるので、<button>
要素で実装しています。
aria-labelledby
属性では、ユニークな id
属性を付与する必要がありますが、そのことを考えなくて良いという利点があります。
フォーム要素を <label>
要素に紐づける
見出し「フォーム要素を 」<label>
要素を <input>
、<select>
、<textarea>
といったフォーム要素と紐づけることで、アクセシブルな名前を指定する方法です。
for
属性と id
属性で明示的(Explicit)に紐づける方法と、フォーム要素を <label>
要素で囲う暗黙的(Implicit)な方法の 2 つのパターンがあります。
特定の子要素を使用する
見出し「特定の子要素を使用する」以下の子要素を含めることで、親要素のアクセシブルな名前として使用することができます。
<fieldset>
要素に対する<legend>
要素<table>
要素に対する<caption>
要素<figure>
要素に対する<figcaption>
要素
ただし、スクリーンリーダーとブラウザの組み合わせによっては、アクセシブルな名前として紐づけされない場合があるので、確実に名前として指定したい場合には aria-labelledby
属性を使用します。
title
属性や placeholder
属性を使用する
この見出しのリンクアクセシブルな名前が空の場合、最終的に title
属性や placeholder
属性がフォールバックとして使用されることがあります。
「4. ブラウザのフォールバックを避ける」で述べたように、この方法はアクセシビリティ上の問題が発生しやすいため推奨されません。
優先順位
見出し「優先順位」ここまで、さまざまなアクセシブルな名前の指定方法を見てきましたが、同一の要素に複数の名前が競合している場合には、優先順位によって適用される名前が決まります。
以下のコードにおいて、<button>
要素のアクセシブルな名前は何になるでしょうか。
この場合、もっとも優先度の高い aria-labelledby
属性が適用されるため、アクセシブルな名前は foo
になります。デベロッパーツールで調べると、どの名前が有効・無効になっているかを簡単に確認することができます。
アクセシブルな名前は以下の順番で評価され、条件が一致すればその時点で名前が決まり、値が空のままであれば次のステップに進みます。
- 1
有効な
aria-labelledby
属性 - 2
有効な
aria-label
属性 - 3
特定の属性や子要素が存在する
-
<input>
のtype
属性がbutton
、submit
、reset
のいずれかの場合のvalue
属性 -
<input type="image">
、<img>
、<area>
のいずれかの場合のalt
属性 -
<fieldset>
の子要素として最初に出現する<legend>
要素 -
上記以外のフォーム要素に紐づけられた
<label>
要素 -
<figure>
の子要素として最初に出現する<figcaption>
要素 -
<table>
の子要素として最初に出現する<caption>
要素
-
- 4
子孫要素のコンテンツ
- 5
フォールバック
-
<input>
のtype
属性がtext
、password
、search
、tel
、url
のいずれか、または<textarea>
の場合のtitle
属性、もしくはplaceholder
属性 -
<input type="submit">
の場合はローカライズされた「submit」の文字列 -
<input type="reset">
の場合はローカライズされた「reset」の文字列 -
<input type="image">
の場合はtitle
属性、もしくは ローカライズされた「Submit Query」の文字列 -
<summary>
の場合は「Details」の文字列 -
上記以外の要素の
title
属性
-
すべての条件に該当しなければ、アクセシブルな名前は空になります。
これらの規則をすべて頭に入れておく必要はありませんが、子孫要素のコンテンツよりも ARIA 属性のほうが強い(ARIA 属性によって上書きされる)ことは意識しておいたほうがよいでしょう。
WCAG 2.x の達成基準
見出し「WCAG 2.x の達成基準」アクセシブルな名前(name)は、支援技術に提示するテキストのため、WCAG 2.x の多くの達成基準に関連しますが、特に関連性が高い 2 つの基準を取り上げます。どちらもレベル A です。
2.5.3 ラベルを含む名前(name)
見出し「2.5.3 ラベルを含む名前(name)」可視テキストや文字画像のラベルが存在する場合、アクセシブルな名前とラベルを一致させるか、ラベルのテキストから始めることが求められます。音声コントロールにおけるアクセシビリティの確保と、スクリーンリーダーにおけるユーザ体験の向上のために必要とされます。
なお、この達成基準は可視テキストのみが対象となり、アイコンのように可視テキストのない要素、または記号として文字が使われている場合(例えば太字を意味する「B」の文字)には対象外です。この場合には、機能や目的を表現した名前が適切です。
4.1.2 名前(name)・役割(role)・値(value)
見出し「4.1.2 名前(name)・役割(role)・値(value)」この達成基準では、支援技術のアクセシビリティを確保するために、適切な名前、ロール、状態、値を指定することが定められています。
基本ルールの「3. ネイティブの技術を優先する」のように、HTML の標準機能を正しく使用すれば、この基準を満たすことが容易になり、反対に独自のコンポーネントを実装しようとすると基準を満たす難易度が高くなります。
アクセシブルな説明
見出し「アクセシブルな説明」アクセシブルな説明(Accessible Description)は補足説明として使用されます。基本的な考え方は、アクセシブルな名前と共通するので簡単に紹介します。
アクセシブルな説明は、おもにスクリーンリーダー向けに提供され、通常は名前やロール、状態などの後に補足説明として読み上げられます。なお、スクリーンリーダーとブラウザの組み合わせや、指定方法によっては、読み上げられないこともあります。
指定する方法はいくつかありますが、ここでは aria-describedby
属性に限定して説明します。
aria-describedby
属性を指定する
この見出しのリンクaria-describedby
属性を使用してアクセシブルな説明を指定する方法です。aria-labelledby
属性と同じく対象となる要素の id
属性と紐づけることで実現します。
なお、aria-labelledby
属性と同様に、参照先の要素が非表示でも説明として有効になるので、特にエラーメッセージをフォーム要素に紐づけるときには注意が必要です。
このとき、エラーメッセージは hidden
属性で隠されていますが、スクリーンリーダーを使用して <input>
要素にフォーカスすると読み上げられてしまいます。そのため、必要に応じて動的にエラーメッセージを生成するといった実装が求められます。
おわりに
見出し「おわりに」この記事では、アクセシブルな名前(Accessible Name)を中心に説明しました。
普段の実装において、取り立てて意識することのないアクセシビリティにおける名前の仕組みですが、調べてみると意外と奥が深いことがわかりました。
まずは、基本ルールを守ることでアンチパターンを避けること、そして何よりもスクリーンリーダーなどを使用したテストの重要性を忘れないようにしたいです。
参考文献
見出し「参考文献」本記事の作成にあたり、以下のウェブページを参考にしました。
- Providing Accessible Names and Descriptions | W3C(外部リンクを開く)
- Decoding Label and Name for Accessibility | WebAIM(外部リンクを開く)
- The order of accessible name computation steps | Stefan Judis(外部リンクを開く)
- Foundations: accessible names and descriptions | TetraLogical(外部リンクを開く)
脚注
-
網羅的な情報は W3C が提供する Providing Accessible Names and Descriptions に掲載されていますが、これらをすべて暗記する必要はなく、判断に迷ったときに参照する程度でよいでしょう。 ↩