Chrome Dev Summit 2018 is happening now and streaming live on YouTube. Watch now.

アクセシビリティ ツリー

ここでは、スクリーン リーダーのユーザー専用のユーザー インターフェースを作成するものとします。視覚的な UI を作成する必要はまったくありませんが、スクリーン リーダーで使用するために十分な情報を提供します。

ここで作成するのは、DOM API と同様にページの構成を示す一種の API ですが、情報の多くは視覚表示にのみ効果があるため、情報もノードも少なくて済みます。次のようになります。

スクリーン リーダー DOM API モックアップ

これは基本的に、ブラウザが実際にスクリーン リーダーに提示する内容です。ブラウザは DOM ツリーを取得して、支援技術に使いやすい形式に変更します。この変更したツリーをアクセシビリティ ツリーと呼びます。

このアクセシビリティ ツリーは、たくさんのリンクがあり、画像が少なく、フィールドやボタンが含まれ、90 年代の古いウェブページのようなイメージです。

1990 年代スタイルのウェブページ

このようなページを下に向かって見ていくと、スクリーン リーダーのユーザーと同様のエクスペリエンスが得られます。インターフェースはありますが、シンプルかつ直接的で、アクセシビリティ ツリーのインターフェースに非常によく似ています。

アクセシビリティ ツリーは、ほとんどの支援技術で利用されています。フローは次のようになります。

  1. アプリケーション(ブラウザなどのアプリ)が API を介して、セマンティックな UI を支援技術に提供します。

  2. 支援技術は API を介して読み取った情報を使用し、代替ユーザー インターフェースの表現を作成します。たとえば、スクリーン リーダーは、ユーザーがアプリの音声表現を聞き取れるインターフェースを作成します。

  3. 支援技術は違う方法で、ユーザーがアプリを操作できるようにする場合があります。たとえば、ほとんどのスクリーン リーダーは、ユーザーが容易にマウスクリックや指によるタップをシミュレートできるように、フックを提供しています。

  4. 支援技術は、アクセシビリティ API を介してユーザーの目的(「クリック」など)をアプリに伝えます。アプリは、元の UI のコンテキストでそのアクションを適切に解釈する必要があります。

ウェブブラウザの場合、指示ごとに追加のステップがあります。ブラウザは実際のところ、ブラウザ内部で実行するウェブアプリのプラットフォームだからです。そのためブラウザは、ウェブアプリをアクセシビリティ ツリーに変換し、支援技術から受け取ったユーザーのアクションに基づいて、JavaScript で適切なイベントが発行されるようにする必要があります。

しかし、ブラウザが行う処理はそれだけです。ウェブ デベロッパーとしての役割は、このような流れを認識したうえで、このプロセスを活用できるウェブページを開発し、ユーザーがアクセスできる環境を整えることです。

そのためには、ページのセマンティクスを正しく表現して、ページ内の重要な要素に適切な役割、状態、プロパティが存在し、アクセス可能な名前と説明を指定していることを確認する必要があります。そうすればブラウザ側で、支援技術がその情報にアクセスして、カスタマイズされたエクスペリエンスを作成できるようにすることが可能です。

ネイティブ HTML のセマンティクス

DOM の多くはセマンティックな意味を暗黙的に示しているため、ブラウザは、DOM ツリーをアクセシビリティ ツリーに変換できます。つまり、DOM は、ブラウザによって認識され、さまざまなプラットフォームで予測可能な形で動作するネイティブ HTML 要素を使用します。よって、リンクやボタンといったネイティブ HTML 要素のアクセシビリティは、自動的に処理されます。この組み込みのアクセシビリティを活用するには、ページ要素のセマンティクスを表す HTML を記述します。

ただし、ネイティブ要素のように見えるけれども実際は異なる要素を使用することもあります。たとえば、この「ボタン」は実際にはボタンではありません。

これを HTML で作成する方法は数多くありますが、一例を示します。

<div class="button-ish">Give me tacos</div>

実際のボタン要素を使用しないときは、それがどのような要素なのか、スクリーン リーダーは知る術がありません。また、tabindex を追加して、キーボードのみで操作するユーザーにも使用可能にするという追加の作業が必要になります。現状のコードのままでは、マウスがなければ使用できないからです。div の代わりに通常の button 要素を使用すれば、この問題は簡単に解決できます。ネイティブ要素を使用すれば、キーボード操作に対応できるというメリットもあります。ネイティブ要素を使用するからといって、魅力的な視覚効果を諦める必要はありません。ネイティブ要素のスタイルを指定して目的の外観を実現し、しかも暗黙的なセマンティクスと動作を維持することができます。

先ほど説明したとおり、スクリーン リーダーは要素の役割、名前、状態、値を通知します。 適切なセマンティクス要素、役割、状態、値の使用については説明しましたが、さらに要素の名前を検出可能にする必要があります。

大まかに、名前には以下の 2 つのタイプがあります。

  • 表示可能なラベル。すべてのユーザーがこのラベルの意味と要素を関連付けます。

  • 代替テキスト。視覚的なラベルが不要なときにのみ使用されます。

テキストレベルの要素の場合、なにもする必要はありません。定義すれば、なんらかのテキストのコンテンツがあるからです。しかし、入力要素やコントロール要素、画像のような視覚的なコンテンツの場合、名前を指定していることを確認する必要があります。実際、テキスト以外のコンテンツに代替テキストを指定することは、WebAIM チェックリストの最初の項目に挙げられています

その方法の 1 つは、推奨案に従い「フォームの入力要素に、関連するテキストのラベルを付ける」ことです。ラベルと、チェックボックスなどのフォーム要素を関連付ける方法は 2 つあります。いずれかの方法で、ラベルテキストをチェックボックスのクリック ターゲットにすると、マウスのユーザーにもタッチスクリーンのユーザーにもメリットがあります。ラベルと要素を関連付けるには、次のいずれかを実行します。

  • ラベル要素内に入力要素を配置する
<label>
  <input type="checkbox">プロモーション情報を受け取る</input>
</label>

インテントまたは

  • ラベルの for 属性を使用して、要素の id を参照する
<input id="promo" type="checkbox"></input>
<label for="promo">プロモーション情報を受け取る</label>

チェックボックスのラベルを適切に設定すると、スクリーン リーダーは要素にチェックボックスの役割があり、オンの状態で、「プロモーション情報を受け取る」という名前が付いていることを報告できます。

VoiceOver から出力された画面上のテキスト。チェックボックスの読み上げ用のラベルを示しています

ポイント: 実際にスクリーン リーダーを使用して、ページ内をタブで移動しながら、読み上げられる役割、状態、名前を確認すると、不適切に関連付けられたラベルを見つけることができます。