「アクセシブルな名前」「アクセシブルネーム」という用語は、WebアクセシビリティやWAI-ARIAの解説にしばしば登場します。しかし、英語の「Accessible Name」をそのままカタカナ混じりの日本語に訳したこの言葉が何を指しているのかは、字面からは掴みきれないのではないかと思います。
「アクセシブルな名前」が関係するものを説明するときに、この用語の扱いにいつも苦労します。そこで、そういうときに参照できる解説として、この記事を書いてみています。
この記事で伝えたいこと
- アクセシブルな名前は、アクセシビリティツリー上での「名前(Name)」プロパティであり、要素の目的や意味を表す重要なものです
- アクセシブルな名前は、表示されるテキストや、
alt
属性、<label>
要素によって付けられます。これらの使用が困難な場合にはaria-label
属性とaria-labelledby
属性を使用します。 - アクセシブルな名前を確認するには、スクリーンリーダーやブラウザの開発者ツール、Accessibility Visualizerを使用できます。lintツールやaxe-coreにより、指定漏れを機械的に発見することもできますが、内容が妥当であるかは人間が確認する必要があります
WAI-ARIAとアクセシビリティツリー
スクリーンリーダーのような、心身の障害などによる不便のあるユーザーを補助をするソフトウェアやハードウェアを総称して、「支援技術」と呼びます。支援技術がWebコンテンツと連携するうえでの仕様を定めているのが WAI-ARIA です。「アクセシブルな名前」はWAI-ARIAの仕様書に登場する概念です。
このあたりの詳しい話は、role 属性とは、aria-* 属性とは、WAI-ARIA とは、いったい何なのか、いつ使うべきなのか という記事にまとめてあります。
WAI-ARIAが規定するもののひとつに、 アクセシビリティツリー または アクセシビリティオブジェクトモデル (Accessibility Object Model: AOM)があります。これは、Webページ上にある情報のうち、支援技術に伝わるべきものをツリー状に表現したモデルです。アクセシビリティツリー上に、ページ内のさまざまなものの「意味」(WAI-ARIAセマンティクス)が表現されることで、支援技術はそれを読み取り、ユーザーにWebコンテンツ上の情報を提示したり、ユーザーの操作をWebコンテンツに伝達したりできるようになります。
アクセシブルなオブジェクト
アクセシビリティツリーは、「アクセシブルなオブジェクト(Accessible Object)」によるツリー構造となっています。ひとつひとつのアクセシブルなオブジェクトは、HTML1による要素やテキストノードと対応関係にあります。JavaScriptに向けてすべての要素へのアクセス手段を提供するDOMと違い、CSS等によって不可視になっている要素は、アクセシビリティツリーでは無視されます。
ここでいう「アクセシブル」とは、「支援技術からアクセスできる」くらいの意味です。HTML要素は、特別なことを何もしなくてもアクセシブルなオブジェクトになるし、アクセシブルなオブジェクトがあるからアクセシビリティが高いというわけでもありません。
アクセシブルなオブジェクトは、それぞれが「ロール」「プロパティ」「ステート」を持ち、これらの情報が支援技術に伝わることで、ユーザーは支援技術を通してWebコンテンツの情報を読んだり、操作したりできるようになります。どんなロール・プロパティ・ステートが存在するのかは、WAI-ARIAの仕様として定義されています。
たとえば、以下のようなHTMLについて考えてみます。
<input
type="checkbox"
name="subscribe_news"
id="subscribe_news_checkbox"
class="checkbox_input">
<label
for="subscribe_news_checkbox"
class="checkbox_label">
最新情報をメールで受け取る
</label>
上記のうち、 <input>
要素はチェックボックスとなります。このチェックボックスは、アクセシビリティツリー上では以下のようなロール・プロパティ・ステートを持つ、アクセシブルなオブジェクトとなります。
ロール | checkbox |
---|---|
プロパティ |
|
ステート |
|
name
属性や id
属性や class
属性のように、ユーザーが知覚しないであろう情報は、アクセシビリティツリーには反映されません。また、 <label>
要素の for
属性の値にこの <input>
要素の id
属性の値と同じものが入ったことで、「名前」プロパティには <label>
要素の内容が反映されています。ロールは、この要素がチェックボックスであることを表し、そして「チェック」ステートは、ユーザーのクリック操作によって「チェックされている」に変化することでしょう。
スクリーンリーダーはこのチェックボックスについて「チェックボックス チェックなし 最新情報をメールで受け取る」のように読み上げるでしょう(読み上げ方はスクリーンリーダーの種類や設定により異なります)。
これにより、視覚的にチェックボックスが見えていないユーザーでも、最新情報の書かれたメールを受け取るか否かのチェックボックスが、チェックされていない状態でそこにあることがわかり、メールを受け取りたければチェックを入れる操作をすることもできるようになります。
なお、「ロール」については、Webアクセシビリティにおける、ロール(role)の解説という記事で解説しています。
なぜアクセシブルな名前が重要なのか
先ほどの例でお気づきかもしれませんが、アクセシブルな名前とは、「アクセシブルなオブジェクト」の「名前」プロパティのことです。この名前プロパティは、そのオブジェクトの意味や目的を表現します。
アクセシブルなオブジェクトが持てるプロパティやステートは、ロールによって決められていますが、「名前」を持つことが必須としているロールも存在します。
たとえば、リンク(link
ロール)は名前が必須とされています。以下のようなHTMLによって作られたリンクは、「リンク Qiita」のように読まれるはずです2。これは、<a>
要素によって作られたリンクのアクセシブルなオブジェクトが、要素内の「Qiita」という文字列を名前プロパティとして持つことによります。ユーザーは「Qiita」というテキストから、リンクの意味や目的を理解することができます。
<a href="https://qiita.com/">
Qiita
</a>
ところが、以下のように、リンクを文字でなく画像にして、代替テキスト(alt
属性)はつけていない状態にすると、スクリーンリーダーはこのリンクをどう読み上げるべきかわからなくなってしまいます3。
<a href="https://qiita.com/">
<img src="./logo.png">
</a>
画像(img
ロール)も、名前が必須です。画像における名前は「代替テキスト」と呼ばれ、画像が表現しているものを代替テキストとしてテキストで表現することで、画像が見えない状況のユーザーに意味を伝えることができます。
<img>
要素は、alt
属性に代替テキストとなる文字列を指定することによって、アクセシブルなオブジェクトの名前プロパティがセットされます。
以下のように実装することにより、「リンク 画像 Qiita」と読み上げることができるようになります。 アクセシブルな名前は、ユーザーにUIが何であるかを伝えるために必要なもの なのです。
<a href="https://qiita.com/">
<img src="./logo.png" alt="Qiita">
</a>
先ほどのチェックボックスの例でも、「最新情報をメールで受け取る」という名前があるおかげで、チェックボックスの目的が何であるかが明確です。もし名前がついていなければ、スクリーンリーダのユーザーはチェックボックスの前後を読んで、チェックボックスの目的、つまりチェックを入れたらどうなるのかを推測しなければなりません。複数のチェックボックスが連続する画面では、チェックボックスの前のテキストと後ろのテキストのどちらが目的を表しているのかわかりづらくなることもあります(チェックボックスの目的を表すテキストがチェックボックスの前にあるケースは、少なからず存在します!)。
アクセシブルな名前の付け方
アクセシブルな名前の算出方法は、Accessible Name and Description Computationに定義されています。しかし、この定義は要素や属性の優先順位に触れていて非常に複雑です。これを読み解く必要があるのは、Webブラウザの開発者や支援技術の開発者、アクセシビリティチェックツールの開発者、それらの技術的な解説の著者くらいです。
一般のWeb開発者は、どんな要素や属性でアクセシブルな名前が付けられ、そのうちどれを使うべきなのかを理解しておけば充分でしょう。以下にその内容を示します。
子要素や、表示されているテキストがアクセシブルな名前になるケース
<a>
要素によるリンク、 <button>
要素によるボタン、 <h1>
要素から <h6>
要素による見出しなどは、子要素のテキストがそのままアクセシブルな名前となります。
また、<input type="submit">
や <input type="button">
のように value
属性の値が表示されるものは、その値がアクセシブルな名前になります。
<h1>ここがアクセシブルな名前</h1>
<a href="https://example.com/">
ここがアクセシブルな名前
</a>
<button>ここがアクセシブルな名前</button>
<input type="submit" value="ここがアクセシブルな名前">
そのため、テキストが表示されている限りは、アクセシブルな名前についての問題は起きないと言ってよいでしょう。画像など、テキストを使わずにリンクやボタンや見出しの見た目を作っている場合には、表示されるテキスト以外の方法でアクセシブルな名前をつけなければ問題が発生します。
代替テキスト用の属性が用意されているケース
<img>
要素の alt
属性は、画像の代替テキストのための属性であり、それは画像というアクセシブルなオブジェクトに、名前プロパティを与える方法でもあります。
<img>
要素以外にも、画像をボタンにするための <input type="image">
や、 イメージマップに使用される <area>
要素も alt
属性をもちます。
これらの alt
属性は、HTMLの仕様書では「必須」とされています。ただし、装飾目的で配置される、ユーザーに伝わるべき意味を持たない画像の <img>
要素は、alt
属性を空にする(alt=""
)ことで、支援技術に画像を存在ごと無視させることができます。ユーザーに伝わるべき意味をもつ画像のalt
属性は空にしてはいけません。
<img
src="path/to/image"
alt="画像のアクセシブルな名前">
<input
type="image"
src="path/to/image"
alt="画像ボタンのアクセシブルな名前">
<img
src="path/to/map"
usemap="#map"
alt="画像のアクセシブルな名前">
<map name="map">
<area
shape="rect"
coords="10,10,40,40"
href="https://example.com"
alt="マップ内のリンクのアクセシブルな名前">
</map>
アクセシブルな名前を付けるための要素が用意されているケース
フォームの入力欄に使われる <input>
<select>
<textarea>
要素は、 <label>
要素によって名前を付けることができます。入力欄のグループ化に使われる <fieldset>
要素は、最初のか要素が <legend>
要素の場合、 <legend>
要素の内容で名前付けされます。
入力欄の要素は、それ単体では何を入力するべき入力欄なのか、ユーザーにはわかりません。普通はその入力欄の目的を表すテキスト(または、テキストに替わる要素)を並べて配置するはずで、そのための要素として <label>
要素が用意されています。
<label>
要素は、 for
属性に入力欄の要素の id
属性値を指定する方法でも、 <label>
要素内に名前として使用したいテキストや要素と入力欄の要素の両方を配置する方法でも、どちらでも名前付けができます。
<label>
要素で使用するか否かに関わらず、 id
属性値は必ずHTML文書内で一意な、重複しない値である必要があります。
<label for="input">
テキスト入力欄のアクセシブルな名前
</label>
<input type="text" id="input">
<label>
label要素内の入力欄のアクセシブルな名前
<input type="text">
</label>
<label for="select">
セレクトボックスのアクセシブルな名前
</label>
<select id="select">
<option value="1">選択肢1</option>
<option value="2">選択肢2</option>
</select>
<label for="textarea">
テキストエリアのアクセシブルな名前
</label>
<textarea id="textarea"></textarea>
<fieldset>
要素も同様で、入力欄がグループ化されるのには何らかの目的があるはずで、それを表現するために <legend>
要素が用意されています。これらは名前付けのための要素なのです。
<fieldset>
<legend>ここがfieldset要素のアクセシブルな名前</legend>
<label>
<input
type="radio"
name="radio_group"
value="1">
ここが1つめのラジオボタンのアクセシブルな名前
</label>
<label>
<input
type="radio"
name="radio_group"
value="2">
ここが2つめのラジオボタンのアクセシブルな名前
</label>
</fieldset>
<label>
要素を使用すると、 <label>
要素の部分をクリックしたときに紐づけられた入力欄をクリックした時と同じように、入力欄にフォーカスが移動したりチェックボックスやラジオボタンのチェックが入ったりします。これは紐付けが正しくできているかの確認に使えるほか、特にチェックボックスやラジオボタンについてはクリックやタップに反応する部分の面積が広がり、操作性の向上にも繋がります。
aria-label
属性と aria-labelledby
属性
WAI-ARIAで定義されている role
属性や aria-
で始まる名前の属性を使うと、アクセシブルなオブジェクトのロール、プロパティ、ステートを書き換えることができます。名前プロパティの書き換えには、aria-label
属性と aria-labelledby
属性が使用できます。これらの属性は、子要素や他の属性よりも優先して、アクセシブルな名前として使用されます。
ただし、 これらの属性は、他の手段が使えない場合の最終手段であるべきです 。
-
aria-label
属性に設定されたテキストは、視覚的には表示されないため、表示内容と食い違った状態になっていても気付きにくくなります -
<label>
要素のように、テキストをクリックした時に入力欄へフォーカスを移すような挙動は、JavaScriptで再現したりしない限り実現しません - 不用意に
aria-label
属性やaria-labelledby
属性を使用することで、視覚的に表示されている内容に、支援技術からはアクセスできなくなってしまうおそれがあります - 名前付けの禁止されているロールでは
aria-label
属性やaria-labelledby
属性を使用できない制約があります(それを把握するためには、WAI-ARIAの仕様書を読んで理解する必要があります) -
aria-label
属性やaria-labelledby
属性の指定は強力なため、適切なマークアップにより正しく名前付けをしているものを上書きしてしまいます
たとえば、既存の画面を最小限の工数で支援技術から利用できる状態にしたい場合には、 aria-label
属性や aria-labelledby
属性を使うことになるかもしれません。
ほかにも、aria-label
属性や aria-labelledby
属性を使うことでしかアクセシブルな名前を付けられないロールやHTML要素がいくつかあります。それらに aria-label
属性や aria-labelledby
属性によって名前を付ければ、支援技術のユーザーにとって使いやすさが高まるかもしれません。
この記事と重複する部分も多いですが、aria-label
属性に関する記事も書いているので、参考にしてください。
名前付けを目的にしているわけではない属性が(仕方なしに)使われるケース
ここまでに紹介したような、要素内のテキストや、名前付けのための要素や属性を使用できない場合には、 title
属性や placeholder
属性がアクセシブルな名前として使用されるようになっています。ただしこれは、適切にマークアップされていないWebコンテンツが支援技術でも使えるよう、仕方なしに用意されていると解するべきものです。
支援技術のユーザーにとっては使えないよりは使えたほうが良いわけで仕様に組み込まれていますが、 製作者が依存するべきものではありません 。
title
属性は、マウスポインタを乗せること(マウスオーバー)で表示される、ツールチップの内容を記載できる属性です。HTMLでは、あらゆる要素に付けて良いグローバル属性として定義されています。<img>
要素の alt
属性や、 <label>
要素と紐付いていない <input>
<select>
<textarea>
要素に、aria-label
属性や aria-labelledby
属性による名前付けもなく、 title
属性がある場合、これがアクセシブルな名前として使用されます。
しかし、ツールチップには、以下のような問題があります。そのため、HTMLの仕様書には title
属性の項に、ツールチップに依存することを推奨しない旨の記載があります。
- スマートフォンやタブレットのタッチスクリーンや、マウスポインタを使わずキーボードのみで操作している場合には、ツールチップの内容を確認できません
- ツールチップが存在するか否かは、実際にマウスオーバーしてツールチップが表示されるまでわかりません
placeholder
属性は <input>
<textarea>
要素によるテキスト入力欄に、入力前に表示されるプレースホルダーテキストを指定する属性です。 <label>
要素、 aria-label
属性や aria-labelledby
属性、title
属性による名前付けができない場合、placehodler
属性の値がアクセシブルな名前として使用されます。
プレースホルダーテキストは、テキスト入力をし始めると非表示になってしまうため、入力中に確認できなくなり、入力欄の目的を示す用途には不適切です。その他にもプレースホルダーテキストの使用にはいろいろな問題がつきまといます。詳しくは入力欄のプレースホルダーって結局どうなのという記事にまとめてあります。
アクセシブルな名前の確認
先述の通り、アクセシブルな名前は、要素の意味や目的を表すものとして、ロールによっては必須となっています。ここまで紹介した要素や属性による指定をコードの上で行うのはもちろんのこと、それが実際にアクセシビリティツリーに反映されていることを確認したり、不適切な状態を見つける方法も必要です。
スクリーンリーダーでの確認
最もシンプルで確実な確認方法は、「スクリーンリーダーで読んでみる」ことでしょう。スクリーンリーダーにはいろいろな種類がありますが、アクセシブルな名前の確認だけであれば、1種類のスクリーンリーダーの確認でも充分です。WindowsであればNVDA日本語版をインストールして使用することをおすすめします4。macOSであれば標準搭載のVoiceOver を使用します。
それぞれのスクリーンリーダーには非常にたくさんの機能が搭載されていますが、アクセシブルな名前の確認だけであれば、スクリーンリーダーの起動・終了の方法と、スクリーンリーダーカーソルを移動させる基礎的な操作方法さえ憶えておけば問題ありません。以下に、それぞれのスクリーンリーダーの操作方法へのリンクを載せます。
ブラウザの開発者ツールでの確認
各ブラウザの開発者ツールにも、アクセシビリティツリーを確認する機能があります。
Chromeの場合、デベロッパーツールの「Elements(要素)」パネルで選択した要素のアクセシブルなオブジェクトを、「Accessibility(アクセシビリティ)」タブで見ることができます。「Computed Properties(計算済みプロパティ)」のセクションに、「Name」として表示されているものがアクセシブルな名前です。
Firefoxでは、「アクセシビリティ」パネルで、ページ全体のアクセシビリティツリーを閲覧することができます。同等の機能は、Chromeでも「Enable full-page accessibility tree」を有効にすることで実現できます。
自動チェックツールでの確認
スクリーンリーダーによる確認も、開発者ツールによる確認も、開発者による能動的な「確認」行為を必要とします。アクセシブルな名前が必要とされる箇所を能動的に見にいかなければ、不適切な状態を発見できません。必須とするからには自動的に問題を発見できるようにしたいものです。
Markuplint、eslint-plugin-jsx-a11y、eslint-plugin-vuejs-accessibility、Biomeなどのlintツールには、alt
属性や <label>
要素に関する問題を指摘するルールがあります。エディタと連携させたり自動的にチェックが実行されるようにすることで、早い段階で問題を発見することができます。ただし、コンポーネントの単位でファイルを分割したりしていると、ルールをすり抜けてしまうコードが書けてしまったり、あるいはルールに適合するコードを書くことができず、無効化せざるを得なくなったりすることもあります。
axe-coreにも、アクセシブルな名前が未設定となっていることで問題となる要素に対して警告するルールが存在します。axe-coreはアクセシビリティチェックの専用ライブラリで、axe DevTools拡張機能やLighthouseを使うことで、ブラウザ上でいま見ているページを対象にアクセシビリティチェックを行うことができます。CIに組み込むことで、開発中やリリース前に自動的なチェックをすることもできます。
Accessibilty Visualizerでの確認
lintツールやチェックツールによる機械的なチェックでは、アクセシブルな名前が必要な場所に存在することの確認はできますが、その内容が正しく意味や目的を伝えているかどうかまでは判断してくれません。「あああああ」のような無意味な文字列になっていても、間違った内容になっていても、チェックは通過してしまいます。
そのため、機械的なチェックを導入していても、人間による確認は必要になります。とはいえ、開発者ツールでひとつひとつの要素を見ていくのは手間がかかりますし、スクリーンリーダーの操作方法は憶えるのも大変で、すべての開発者が日常的に行うにはハードルの高いものです。
そこで、Accessibility Visualizerという、手軽にアクセシブルな名前のほか、アクセシビリティツリーで読み取れる情報を可視化できるブラウザ拡張を開発しています。
Accessibility Visualizerを使用すると、アクセシブルな名前は、緑色の人型のアイコンで表示されます
アクセシブルな名前が必要なのに設定されていない場合には、赤い警告が表示されます。
機械的なチェックと併用することで、特にアクセシブルな名前の内容がおかしくなっていたりすることに気付けるようにすることを意図しています。
Accessibility Visualizerだけでは必ずしもすべての場面のすべての要素をカバーできませんし、画面の挙動に影響を与えてしまうこともあります。Webアクセシビリティに本気で取り組んでいくのであれば、スクリーンリーダーでも確認したり、障害当事者によるテストを行うことを推奨しますが、手軽に確認できる手段として有効なのではないかと思っています。
(Accessibility Visualizerのデモ画像は 駒瑠市〜アクセシビリティ上の問題の体験サイト〜 で、Accessibility Visualizerを使用したものです)
-
WAI-ARIAはホスト言語をHTMLに限定しませんが、わかりやすさを重視して、ほとんどの場合で意識されるHTMLにのみ言及しています。 ↩
-
スクリーンリーダーの音声エンジンや辞書が「Qiita」という固有名詞の読み方を知らない可能性が高く、「Qiita」が「きーた」と読まれない可能性があります。ただし多くの単語、特に固有名詞に関しては常に同じ問題があり、スクリーンリーダーでは1文字ずつ文字を読ませて確認できるため、あまり気にする必要はありません(参考: スクリーンリーダーによる読み間違いへの配慮) ↩
-
スクリーンリーダーによっては、名前のない画像は
src
属性の一部、名前のないリンクはhref
属性の一部を読み上げる、場合によっては画像内の文字がOCRされて読み上げられるなどにより、Qiitaへのリンクであることが推測できる読み上げがなされる可能性はあります。これはスクリーンリーダーがアクセシビリティの低いWebページでもなんとか使えるようにとヒントとなる情報を捻り出しているもので、何がどうユーザーに伝わるかが保証できず、アクセシビリティが高いと言える状況ではありません ↩ -
日本では、PC-Talkerのユーザー数が多く、またWindowsにはナレーターというスクリーンリーダーが搭載されているなかでNVDAをおすすめしているのは、ナレーターよりもユーザー数が多く、読み上げを音声で聞けるものを無料で入手できる(PC-Talkerには無料で入手できるクリエイター版がありますが、音声読み上げ機能が無効化されています)ことによります。 ↩