この翻訳は不完全です。英語から この記事を翻訳 してください。

前回の記事に続いて言えることですが、セマンティックではない HTML や JavaScript によって更新される動的なコンテンツを含むような、複雑な UI コントロールの作成は難しくなることがあります。WAI-ARIA は、ブラウザや assistive technology が認識可能な追加のセマンティックを追加することによってそのような問題に対処し、ユーザーの理解を助けます。ここでは、アクセシビリティを向上させるための基本的な使い方を説明します。

前提知識: 基本的なコンピューターの知識、 HTML 、 CSS 、 JavaScript に対する基本的な理解、 前回の記事に対する理解
学習目標: WAI-ARIA、および、アクセスビリティを向上させるために必要に応じて有用な追加のセマンティックを提供する方法について知識を得ること

WAI-ARIA って何?

まずは、WAI-ARIA とは何か、そして何ができるのかという点から始めましょう。

全く新しい問題

Web アプリがより複雑で動的なものになると、新しいアクセシビリティの機能と問題が明らかになってきます。

例えば、 HTML5 は普遍的なページの機能を定義するためにいくつものセマンティック要素を取り入れました。 (<nav><footer> 等) これらが利用可能になる以前は、開発者は  <div class="nav"> のように単に <div> を ID や class と共に使っていましたが、メインナビゲーションのようなページ内の機能をプログラムで識別する簡単な方法が無いために問題がありました。

初期の解決方法は、ナビゲーションへとリンクさせるため、以下のようにページ上部に1つ以上の隠しリンク (もしくは他の何か) を追加することでした。

<a href="#hidden" class="hidden">Skip to navigation</a>

しかしこれは簡潔な方法ではない上に、スクリーンリーダーがページ上部から読み込む場合にのみ利用できるものでした。

他の例としては、アプリが日付選択のための date picker や値選択のためのスライダーなどの複雑なコントロールを使いだしたケースがあります。HTML5 は、そのようなコントロールをレンダリングするための特別な input タイプを提供しています。

<input type="date">
<input type="range">

これらはブラウザ間で十分にサポートされておらず、またスタイル付けすることが非常に困難であるため、ウェブサイトのデザインに合わせる上で不便となります。結果として、開発者は多くの場合 JavaScript ライブラリを利用して複数のネストされた <div> でそのようなコントロールを生成したり、class 名を持った table 要素に対して CSS によるスタイル付けと JavaScript によるコントロールを行ったりします。

この場合の問題は、見た目上は動作するものの、スクリーンリーダーはそれらが何なのか全く理解できず、ユーザーは意味を成さないごちゃごちゃの要素であるとしか教えられないという点にあります。

WAI-ARIA の導入

WAI-ARIA は W3C によって定められた仕様で、追加のセマンティックを提供するために要素に対して適用可能な一連の HTML 属性を定義しており、どのような場所でもアクセシビリティを向上させます。この仕様では、主に3つの機能があります:

  • Roles — これは要素が何か、もしくは何をするかを定義します。多くの場合はいわゆる landmark roles であり、主に HTML5 構造要素のセマンティックを複製します。例えば、 role="navigation" (<nav>) や role="complementary" (<aside>) などです。しかし、それ以外にも別のページ構造を定義するものもあります。例えば、 role="banner" 、 role="search", role="tabgroup" 、 role="tab" 等で、 UIに多く見られます。
  • Properties — これは要素の性質を定義するものであり、追加の意味やセマンティックを与えるために使用することができます。例えば、 aria-required="true" はフォーム input が有効となるために値を入力しなければならないことを定義し、 aria-labelledby="label" は、要素にIDを追加することで、複数の場合も含めてページ内の他のどの要素からも label として参照することを可能にします。これは <label for="input"> ではできません。 別の例として、 aria-labelledby を使ってキーとなる記述を含む <div> が複数の table のセルの label であると指定することができますし、画像の代替テキストの代わりとして使用することもできます。これは、 alt 属性で繰り返すのではなく、ページの既存の情報を画像の代替テキストとして指定します。 代替テキスト で例を確認することができます。
  • States — 要素の現在の状態を定義する特別なプロパティです。例えば、 aria-disabled="true" は、フォームの input が現在 disabled であることをスクリーンリーダーに対して伝えます。states は properties とな異なり、properties はアプリのライフサイクルを通して変化しないのに対して、 states は主にJavaScriptによって変更されます。

WAI-ARIA 属性の重要な点は、ブラウザのアクセシビリティAPI (スクリーンリーダーはここから情報を取得する) によって提供される情報を除いて、それらはウェブページに何の影響も与えないという点です。WAI-ARIA はウェブページの構造や DOM に影響を与えませんが、 CSSの要素選択で利用することが可能です。

: WAI-ARIA の仕様で、ARIA roles の使用方法と追加情報へのリンクを含む便利なリストを確認することができます。 Definition of Roles を見てください。

この仕様では、properties と states の追加情報を含んだリストも確認することができます。 Definitions of States and Properties (all aria-* attributes) を見て下さい。

WAI-ARIA はどこでサポートされていますか?

この質問に答えるのは簡単ではありません。以下理由より、どこで、WAI-ARIA のどの機能がサポートされているのかを記述する決定的なりソースを見つけることが難しいためです。

  1. WAI-ARIA には大量の機能がある
  2. 検討しなければいけないオペレーティングシステム、ブラウザ、スクリーンリーダーの組み合わせが大量にある

最後の点は重要です。そもそもスクリーンリーダーを使用するためには、オペレーティングシステムが所定のアクセシビリティ API を持つブラウザを動作させる必要があり、それはスクリーンリーダーが動作するために必要となる情報を提供しなければいけません。ほとんどの人気の OS は、スクリーンリーダーが動作可能である1つか2つの所定のブラウザを持っています。Paciello Group は、この件に関してほぼ最新のデータを投稿しています。 Rough Guide: browsers, operating systems and screen reader support updated を見て下さい。

次に、ブラウザが問題となっている ARIA の機能をサポートしているのか、および API を通してそれらを公開しているのかという点を気にする必要があります。しかし、スクリーンリーダーがそれらの情報を認識し、意味のある形でユーザーに伝えているのかという点もまた気にしなければいけません。

  1. ブラウザのサポート状況は概ね良いです。本記事の執筆時点で、 caniuse.com は全体のブラウザの WAI-ARIA のサポート状況は88%だとしています。
  2. スクリーンリーダーの ARIA のサポート状況はそこまでではありませんが、多くの一般的なスクリーンリーダーはそれに近いものになってきています。Powermapper による WAI-ARIA Screen reader compatibility の記事で、サポート状況を確認することができます。

この記事では、全ての WAI-ARIA の機能と詳細についてカバーするわけではありません。代わりに、あなたが知るべき最も重要な WAI-ARIA の機能についてカバーします。もしサポートの詳細について何も記述してしない場合は、その機能が十分にサポートされていると想定してください。この例外がある場合は、明確に記述します。 

: JavaScript ライブラリには WAI-ARIA をサポートしているものがありますが、それはライブラリが複雑なフォームコントロールのような UI を生成した場合に、アクセシビリティを向上させるための ARIA 属性を追加することを意味します。迅速なUI開発のためにサードパーティーの JavaScript ライブラリを探しているのであれば、その決断を下す際、UIのアクセシビリティのサポートを重要な要素として必ず考慮すべきです。良い例としては、 jQuery UI (About jQuery UI: Deep accessibility support を見て下さい)、 ExtJS 、 Dojo/Dijit があります。

いつ WAI-ARIA を使うべき?

私達は WAI-ARIA が作られるに至ったいくつかの問題について最初の方で話しましたが、基本的には WAI-ARIA が有用となる4つの主な場面があります。

  1. 道しるべ/ランドマーク (Signposts/Landmarks): ARIA の role 属性の値は、HTML 要素のセマンティック (例: <nav>) を再現する Landmark として振る舞ったり、 search 、 tabgroup 、 tab 、 listbox のようにHTML5 セマンティックの範囲外となる道しるべ (signpost) を異なる機能エリアに提供することができます。
  2. 動的なコンテンツの更新: スクリーンリーダーは、コンスタントに更新されるコンテンツが得意ではない傾向があります。ARIA の aria-live を使うことで、 XMLHttpRequest や DOM API を通してコンテンツが更新された場合に、スクリーンリーダーのユーザーに対してそれを伝えることができます。
  3. キーボードのアクセシビリティの向上: キーボードのアクセシビリティを最初から持つ HTML 要素がありますが、 JavaScript を使ってそれ以外の要素に同じようなインタラクションをさせる場合、スクリーンリーダーにとって困難が生じます。こうしなければならない場合、 WAI-ARIA は他の要素に対してフォーカスを得る手段を提供しています。  (tabindex の使用).
  4. セマンティックではないコントロールのアクセサビリティ: ネストした一連の <div> が CSS/JavaScript と共に複雑な UI 機能を構成していたり、ネイティブのコントロールが JavaScriptによって大きく強化/変更されている場合、アクセシビリティの提供は困難になります。そこにセマンティックや手がかりが無ければ、スクリーンリーダーのユーザーはその機能が何をするのか判断するのが難しくなるでしょう。このような状況では、 button 、 listbox 、または tabgroup といった role の組み合わせ、もしくは aria-required や aria-posinset などの property により機能の手がかりを提供することで、 ARIA は足りないものを補うことができます。

一点忘れてはいけないのが、 WAI-ARIA は必要な場合のみ使用するという点です。理想的には、スクリーンリーダーのユーザーの理解に必要となるセマンティックの提供は、常に ネイティブの HTML 機能  を使用して行うべきです。しかし、コードの制御が限定されていたり、 HTML 要素への実装が容易ではない複雑なものを作っているなどの理由で、これが困難となるケースがあります。そのような場合、 WAI-ARIA はアクセシビリティを向上させる上で価値のあるツールとなります。

もう一度言いますが、必要な時だけ使って下さい!

: 実際のユーザーによってあなたのサイトをテストすることも忘れないでください。障害のあるユーザーではなく、スクリーンリーダーを使用するユーザー、キーボードナビゲーションを使用するユーザーなどです。どれだけうまく動作するかという点で、彼らはあなたよりもうまく観察してくれるでしょう。 

実際的な WAI-ARIA の実装

次のセクションでは、実際の例と共に、より詳細な4つのエリアを見てみます。続行する前に、これから見る例をテストできるように、スクリーンリーダーのテスト環境を用意してください。 

詳細は スクリーンリーダーのテスト を確認してください。

道しるべ/ランドマーク (Signposts/Landmarks)

WAI-ARIA は role 属性 をブラウザに追加することで、必要に応じてあなたのサイトに付加的なセマンティックの値を追加することができます。これが有用となる最初の領域は、スクリーンリーダーのユーザーが共通のページ要素を見つけることができるようになる情報の提供です。例を見てみましょう。私達の website-no-roles の例 (実際の動作) は、以下の構造を持っています。

<header>
  <h1>...</h1>
  <nav>
    <ul>...</ul>
    <form>
      <!-- search form  -->
    </form>
  </nav>
</header>

<main>
  <article>...</article>
  <aside>...</aside>
</main>

<footer>...</footer>

もしあなたがモダンなブラウザでスクリーンリーダーのテストをした場合、いくつかの有用な情報を手に入れるでしょう。例えば、 VoiceOver は以下の内容を読み上げます:

  • <header> 要素の上 — "banner, 2 items" (ヘディングと <nav> を含んでいる)
  • <nav> 要素の上 — "navigation 2 items" (リストとフォームを含む)
  • <main> 要素の上 — "main 2 items" (articleとasideを含む)
  • <aside> 要素の上 — "complementary 2 items" (ヘディングとリストを含む)
  • 検索フォーム入力の上 — "Search query, insertion at beginning of text"
  • <footer> 要素の上 — "footer 1 item"

VoiceOver の Landmarks メニューを見ると (VoiceOver キー + U でアクセスし、カーソルキーでメニューを選択する) 、多くの要素が素早くアクセスできるように綺麗に並んでいることが確認できます。

しかし、これは改善することができます。検索フォームはユーザーが見つけたいと考える重要な Landmark ですが、ここでは Landmarks メニューの中に列挙されておらず、検索 input (<input type="search">) であるということ以上に目立つ Landmark としても扱われていません。 加えて、いくつかの古いブラウザ (特にIE8) は HTML5 要素のセマンティックを認識しません。

ARIA の機能を使用してこれを改善しましょう。まず、 HTMLに対していくつかの role 属性を追加します。私達のオリジナルファイルをコピーするか (index.html と style.css を参照) 、 website-aria-roles の例 (実際の動作) へ移動すると、以下の構造を確認できます:

<header>
  <h1>...</h1>
  <nav role="navigation">
    <ul>...</ul>
    <form role="search">
      <!-- search form  -->
    </form>
  </nav>
</header>

<main>
  <article role="article">...</article>
  <aside role="complementary">...</aside>
</main>

<footer>...</footer>

この例で、私達はあなたにボーナスの機能もあげました。<input> は aria-label 属性が設定されていますが、これは <label> 要素が含まれていない場合でもスクリーンリーダーによって読み上げられる説明ラベルを設定します。こういうケースでは、この機能はとても便利です。このような検索フォームはよくあるものであり、簡単に識別できるので、見えるラベルを設定するとデザインを台無しにしてしまうのです。

<input type="search" name="q" placeholder="Search query" aria-label="Search through site content">

さて、この例を VoiceOver で見た時、以下の改善を確認することができます:

  • ページをブラウジングした時と、 Landmarks メニューで見た時の両方において、検索フォームが分離したアイテムとして認識される
  • フォーム input がハイライトされた時、 aria-label に含まれているテキストが読み上げられる

さらに、このサイトは IE8 のような古いブラウザを使用しているユーザーにとってもアクセシブルとなる可能性が高いので、そのために ARIA role を含める価値もあります。そして、もしあなたのサイトが何らかの理由により <div> のみで構成されているなら、必要なセマンティックを提供するために確実に ARIA role を含めるべきです!

改善された検索フォームは、 HTML5 で利用できるセマンティック以上に ARIA が可能とすることを見せてくれました。あなたは以下の記事、特に Accessibility of non-semantic controls セクションで、より多くのセマンティックや ARIA のプロパティ/属性が持つ力を見ることがでしょう。まずは、 ARIA が動的コンテンツの更新をどのように助けるかを見てみましょう。

動的なコンテンツの更新

DOM に読み込まれたコンテンツ (本文の内容や、画像の代替テキストなど) はスクリーンリーダーを用いて容易にアクセスできます。従って、テキストコンテンツで作られた伝統的で静的なウェブサイトを、視覚的ハンディキャップを持つ人々にとってアクセシブルにすることは容易です。

問題はモダンなウェブアプリケーションが静的なテキストだけを使うことは少ないという点です。それらは動的に更新されるコンテンツ、すなわち、XMLHttpRequest, Fetch, or DOM APIs などの機構を通してページ全体をリロードすることなく更新を行うコンテンツで構成されることが多いです。このような箇所はしばしばライブリージョン (live regions) と呼ばれます。

簡単な例を見てみましょう。aria-no-live.html をご覧ください (もしくは 動作版をご覧ください)。この例では、ランダムに引用文を表示する1つの箱があります:

<section>
  <h1>Random quote</h1>
  <blockquote>
    <p></p>
  </blockquote>
</section>

JavaScript が XMLHttpRequest を通して JSON ファイルを読み込みます。この JSON ファイルには、複数のランダムな引用文とその著者が含まれています。読み込みの完了後に setInterval() ループを開始し、引用文の表示を10秒ごとに新しいものに切り替えます:

var intervalID = window.setInterval(showQuote, 10000);

これは正しく動作しますが、アクセシビリティとしてはよくありません。コンテンツの更新がスクリーンリーダーに検知されないため、ユーザーは何が起こっているかを知ることができないからです。これはつまらない例ですが、更新され続けるコンテンツを多く含む複雑なUIをあなたが作ることを想像してください (チャットルームや戦略ゲームのUI、動的に更新されるショッピングカートの表示など)。ユーザーに更新を知らせる何かしらの手段がない限り、それがどんなに実用的なアプリケーションであっても使いこなすことはできないでしょう。

幸いなことに WAI-ARIA はそのような通知を行う便利な機構を提供しています。それが aria-live プロパティです。このプロパティを要素に適用すると、スクリーンリーダーが更新されたコンテンツを読み上げてくれるようになります。どのような緊急性をもってコンテンツを読み上げてくれるかは、属性値によって変わります:

  • off: デフォルト値。更新は通知されない (should not)。
  • polite: 更新はユーザが暇になったときのみ通知される (should)。
  • assertive: 更新は可能な限り早くユーザに通知される (should)。
  • rude: ユーザを遮ることになったとしても、更新は即座に通知される (should)。

一般的に、発生した順に更新内容を読み上げるには assertive の設定で充分です。一度に複数の変更があっても、順次すべての更新内容が通知されます。rude の設定は、他の通知より優先すべき非常に高い優先度を持つ更新の場合にのみ使うべき (should) です。

aria-no-live.html と quotes.json のコピーを作成し、<section> タグの内容を以下のように更新してください:

<section aria-live="assertive">

これにより、コンテンツの更新があった際にスクリーンリーダーがその内容を読み上げてくれるようになります。

Note: file:// URLをもつページから XMLHttpRequest を呼び出そうとするとほとんどのブラウザはセキュリティ例外を投げます。たとえば、(ダブルクリックなどにより) ファイルを直接ブラウザで読み込んだ場合に file:// URLで開かれます。動作させるためには、 ウェブサーバー (GitHub を利用するなど) やローカルウェブサーバー (Python's SimpleHTTPServer など) にファイルをアップロードする必要があります。

加えて、考慮すべきことがあります。テキストの更新された部分だけを読み上げるべきかどうかです。常に見出し全体を読み上げる方が、何を読み上げられているかをユーザーが認識できるという点で望ましいかもしれません。その対象に aria-atomic プロパティを追加することで、このような動作を得ることができます。手元の <section> タグを再度更新して、以下のようにしてください:

<section aria-live="assertive" aria-atomic="true">

この aria-atomic="true" 属性が、更新された一部分だけではなく、要素の内容を1つのまとまりとして読み上げるようスクリーンリーダーに伝えます。

Note: 完成した例は aria-live.html をご覧ください (もしくは動作版をご覧ください)。

Note: aria-relevant プロパティは live region が更新された際に何が読み上げられるかを制御するのに非常に役に立ちます。たとえば、追加や削除をされた内容だけを読み上げさせることもできます。

キーボードでのアクセシビリティの拡張

このモジュールの他の箇所でも何度か言及したように、アクセシビリティという観点でのHTMLがもつ重要な能力の1つが、キーボードでのアクセシビリティが組み込まれていることです。キーボードから、ボタンやフォームコントロール、リンクなどの機能にアクセスできます。一般的に、タブキーでコントロール間を移動したり、エンター/リターンキーでコントロールの選択や活性化をしたり、必要に応じたその他の制御 (たとえば up や down カーソルでの <select> ボックス内のオプション間の移動) ができます。

しかし、時にはセマンティックでない要素 (ボタンや他のタイプのコントロール) や正しい用途ではないフォーカス可能な要素を利用するコードを書かざるをえないこともあるでしょう。あなたが引き継いだ作りの悪いコードを修正したり、そのようなコードを必要とする複雑なウィジェットを作ったりする場合があるかもしれません。

フォーカスできないコードをフォーカス可能にするために、WAI-ARIA では tabindex 属性を拡張していくつかの値を加えています:

  • tabindex="0" — 上で示したように、この値は通常タブキーでの移動対象とならない要素をタブ移動可能にします。この値は tabindex の値の中で最も便利なものです。
  • tabindex="-1" — この値は通常タブキーでの移動対象とならない要素がプログラム的にフォーカスを受け付けられるようにします。たとえば、JavaScript を利用したりリンクのターゲットとしてフォーカスするケースです。

より詳細な議論や典型的な実装例については、HTML のアクセシビリティに関する記事 —  キーボード・アクセシビリティを呼び戻すように盛り込む をご覧ください。

セマンティックでないコントロールのアクセシビリティ

この節の内容は前節の続きです。多くの入れ子になった <div> 要素と CSS/JavaScript を利用して複雑な UI 機能を構築した場合、また、JavaScript で本来のコントロールの機能を拡張/改変した場合を考えてみましょう。そのようなときには、キーボードでのアクセシビリティが損なわれるだけでなく、スクリーンリーダーのユーザーが各機能のふるまいを理解することは何かの意味づけや手がかりがない限り困難となってしまう。そのような状況においても、ARIA はそこにあるべき意味を補足する手助けができます。

フォーム検査とエラー警告

まず、CSS と JavaScript のアクセシビリティ の記事で最初に見たフォームの例を再検討しましょう (完全なまとめを再び見るには、ひかえめに保つこと をお読みください)。フォームを送信しようとした際に検査エラーがあると現れるエラーメッセージ・ボックスにいくつかの ARIA 属性を含めたことを、その節の末尾で示しておきました。

<div class="errors" role="alert" aria-relevant="all">
  <ul>
  </ul>
</div>
  • role="alert" は、適用先の要素を自動的にライブリージョンにします。すると、その要素に対する変更は読み上げられます。また、role="alert" は、その要素が警告メッセージ (重要であり、時間 / 文脈の影響を受ける情報) なのだ、と意味的に特定しています。かつ、ユーザーに警告を伝える、より優れていてよりアクセシブルな方法も、表現しています (alert() の呼び出しのようなモーダル・ダイアログには、いくつものアクセシビリティの問題があります。WebAIM による Popup Windows を参照)。
  • aria-relevantall という値は、エラー・リストに対して何らかの変更がなされた際には (つまり、エラーが追加または削除された際には) エラー・リストの中身を読み上げるよう、スクリーンリーダーに命令するものです。これは有用です。なぜなら、ユーザーは、リストに何が追加され、リストから何が削除されたのかを知りたいだけでなく、何のエラーが残っているのかを知りたいでしょうからね。

ARIA を使用して、更に先へ踏み込むこともできるでしょうし、なんらかの検査の手助けを更に提供することもできるでしょう。そもそもフィールドが必須かどうかを示すことや、年齢がどの範囲にあるべきかを示すこと、などはいかがでしょうか?

  1. いまの時点で、form-validation.htmlvalidation.js のファイルのコピーをとり、それをローカル・ディレクトリに保存してください。
  2. 両ファイルをテキストエディタで開き、コードがどのように動くのかを見てください。
  3. まず始めに、<form> 開始タグのすぐ上に以下のような段落を加えるとともに、フォームの <label> には、両方ともアスタリスクの印をつけてください。これは、晴眼者ユーザー用に必須フィールドに印をつける通常の方法です。
    <p>Fields marked with an asterisk (*) are required.</p>
  4. これは視覚的に意味をなしますが、スクリーンリーダーのユーザーにとっては、理解するのがそれほど容易ではありません。さいわい、WAI-ARIA には、フォーム入力欄を埋める必要があることをユーザーに伝えるべきだとスクリーンリーダーにヒントを与えるための、aria-required 属性があります。 <input>  要素を次のように更新してください。
    <input type="text" name="name" id="name" aria-required="true">
    
    <input type="number" name="age" id="age" aria-required="true">
  5. この例をここで保存してスクリーンリーダーでテストしてみれば、「Enter your name star, required, edit text (名前を入れてください 星、必須、テキストを編集)」のようなものを聞くことになるはずです。
  6. 年齢の値がどうあるべきかについて、スクリーンリーダーのユーザーと晴眼者のユーザーに知らせるのも、有用かもしれません。これはツールチップとして提示されることがよくあり、あるいは、フォームのフィールド内部のプレースホルダーとして提示されることも、多分あります。最小値と最大値を指定するための aria-valuemin プロパティと aria-valuemax プロパティを、WAI-ARIA は確かに含んではいますが、これらのプロパティは、今のところそれほどちゃんとサポートされてはいないようです。よりちゃんとサポートされている機能は、HTML5 の placeholder 属性です。これは、何の値も入力されていないときに入力欄の中に表示されるメッセージを含むことができ、多くのスクリーンリーダーにより読み上げられます。数値入力欄を以下のように更新してください。
    <input type="number" name="age" id="age" placeholder="Enter 1 to 150" aria-required="true">

: この完成した例を、form-validation-updated.html においてライブ版で見られます。

また、古典的な <label> 要素以上の、ある種の先進的なフォームのラベルづけ技法も、WAI-ARIA によって可能になります。晴眼者のユーザーに対してラベルを可視にしたくない箇所にラベルを設けるために aria-label プロパティを使うことについては、すでに述べました (上記の 道しるべ/ランドマーク (Signposts/Landmarks) の節を参照)。別のプロパティを使う別のラベルづけ技法も、いくつかあります。たとえば、非 <label> 要素をラベルとして指定したいとき、または、同じラベルで複数のフォーム入力欄にラベルづけをしたいときに aria-labelledby を使うとか、別の情報をフォーム入力欄に関連づけてその情報も同様に読み上げさせたいときに aria-describedby を使うとかいったものです。より詳しくは、WebAIM の Advanced Form Labeling の記事 を参照してください。

フォーム要素の状態を示すための有用なプロパティやステートは、ほかにもたくさんあります。たとえば、フォーム・フィールドが無効化されていることを示すには、aria-disabled="true" が使えます。多くのブラウザは、無効化されたフォーム・フィールドを単に飛ばすだけでしょうし、無効化されたフォーム・フィールドは、スクリーンリーダーに読み上げられることすらないでしょう。しかし、無効化されたフォーム・フィールドが認識される場合もあるでしょう。ですから、無効化されている入力欄が実際に無効化されているのだ、とスクリーンリーダーに知らせるために、この (aria-disabled="true" という) 属性を含めておくことは、良い考えです。

もし入力欄の無効化状態が変化する可能性が高いなら、その変化が起きた時点と、その結果どうなったのかを示すことも、良い考えです。たとえば、form-validation-checkbox-disabled.html  のデモには、チェックされると他のフォーム入力欄への更なる情報の入力を可能とするようなチェックボックスがあります。以下の隠しライブリージョンを設定してあります。

<p class="hidden-alert" aria-live="assertive"></p>

これは、絶対的位置指定を使って、視界からは隠してあります。これがチェックされたり、これのチェックが外されたりすると、このチェックボックスのチェックの結果がどうなったのかをスクリーンリーダーのユーザーに伝えるために、aria-disabled ステートやいくつかの視覚的表示を更新するだけでなく、この隠しライブリージョン内部のテキストも更新します。

function toggleMusician(bool) {
  var instruItem = formItems[formItems.length-1];
  if(bool) {
    instruItem.input.disabled = false;
    instruItem.label.style.color = '#000';
    instruItem.input.setAttribute('aria-disabled', 'false');
    hiddenAlert.textContent = 'Instruments played field now enabled; use it to tell us what you play.';
  } else {
    instruItem.input.disabled = true;
    instruItem.label.style.color = '#999';
    instruItem.input.setAttribute('aria-disabled', 'true');
    instruItem.input.removeAttribute('aria-label');
    hiddenAlert.textContent = 'Instruments played field now disabled.';
  }
}

非意味的なボタンをボタンとして説明する

この課程の中で既に二、三回、ボタンやリンクやフォーム要素に本来備わったアクセシビリティ (および、ボタンやリンクやフォーム要素の外見を模倣するために他の要素を使うことの背後に隠れた、アクセシビリティの問題) について述べました (HTML アクセシビリティの記事の UI コントロール と、上記の キーボードでのアクセシビリティの拡張 を参照)。
基本的には、多くの場合、tabindex とほんの少しの JavaScript を使えば、それほど問題を生じずにキーボード・アクセシビリティを追加して呼び戻せます。

しかし、スクリーンリーダーについてはどうでしょうか? スクリーンリーダーはそれでもまだ、そうした要素をボタンとは見なさないことでしょう。もし fake-div-buttons.html の例をスクリーンリーダーで試してみれば、見せかけのボタンは「Click me!, group (クリックしてください!、グループ)」のような語句を使って報告されるでしょうし、それは明らかに混乱を招くものです。

WAI-ARIA ロールを用いてこれを修正できます。fake-div-buttons.html のローカルコピーを作って、ボタンとしての <div> の各々に role="button" と追加してください。たとえば以下のようにします。

<div data-message="This is from the first button" tabindex="0" role="button">Click me!</div>

今や、スクリーンリーダーを使ってこれを試してみれば、「Click me!, button (クリックしてください!、ボタン)」のような語句を使ってボタンを報告させることになるでしょう。ずっと良くなりましたね。

: とはいえ、可能な箇所では正しい意味的要素を使うことの方が常に良いのだ、ということを忘れないようにしてください。もしボタンを作りたいなら、そして <button> 要素が使えるなら、<button> 要素を使うべきです!

複雑なウィジェットを通じてユーザーを案内する

There are a whole host of other roles that can identify non-semantic element structures as common UI features that go beyond what's available in standard HTML, for example combobox, slider, tabpanel, tree. You can see a number of userful examples in the Deque university code library, to give you an idea of how such controls can be made accessible.

Let's go through an example of our own. We'll return to our simple absolutely-positioned tabbed interface (see Hiding things in our CSS and JavaScript accessibility article), which you can find at Tabbed info box example (see source code).

This example as-is works fine in terms of keyboard accessibility — you can happily tab between the different tabs and select them to show the tab contents. It is also fairly accessible too — you can scroll through the content and use the headings to navigate , even if you can't see what is happening on screen. It is however not that obvious what the content is — a screenreader currently reports the content as a list of links, and some content with three headings. It doesn't give you any idea of what the relationship is between the content. Giving the user more clues as to the structure of the content is always good.

To improve things, we've created a new version of the example called aria-tabbed-info-box.html (see it running live). We've updated the structure of the tabbed interface like so:

<ul role="tablist">
  <li class="active" role="tab" aria-selected="true" aria-setsize="3" aria-posinset="1" tabindex="0">Tab 1</li>
  <li role="tab" aria-selected="false" aria-setsize="3" aria-posinset="2" tabindex="0">Tab 2</li>
  <li role="tab" aria-selected="false" aria-setsize="3" aria-posinset="3" tabindex="0">Tab 3</li>
</ul>
<div class="panels">
  <article class="active-panel" role="tabpanel" aria-hidden="false">
    ...
  </article>
  <article role="tabpanel" aria-hidden="true">
    ...
  </article>
  <article role="tabpanel" aria-hidden="true">
    ...
  </article>
</div>

Note: The most striking change here is that we've removed the links that were originally present in the example, and just used the list items as the tabs — this was done because it makes things less confusing for screenreader users (the links don't really take you anywhere; they just change the view), and it allows the setsize/position in set features to work better — when these were put on the links, the browser kept reporting "1 of 1" all the time, not "1 of 3", "2 of 3", etc.

The new features are as follows:

  • New roles — tablist, tab, tabpanel — these identify the important areas of the tabbed interface — the container for the tabs, the tabs themselves, and the corresponding tabpanels.
  • aria-selected — Defines which tab is currently selected. As different tabs are selected by the user, the value of this attribute on the different tabs is updated via JavaScript.
  • aria-hidden — Hides an element from being read out by a screenreader. As different tabs are selected by the user, the value of this attribute on the different tabs is updated via JavaScript.
  • tabindex="0" — As we've removed the links, we need to give the list items this attribute to provide it with keyboard focus.
  • aria-setsize — This property allows you to specify to screenreaders that an element is part of a series, and how many items the series has.
  • aria-posinset — This property allows you to specify what position in a series an element is in. Along with aria-setsize, it provides a screenreader with enough information to tell you that you are currently on item "1 of 3", etc. In many cases, browsers should be able to infer this information from the element hierarchy, but it certainly helps to provide more clues.

In our tests, this new structure did serve to improve things overall. The tabs are now recognised as tabs (e.g. "tab" is spoken by the screenreader), the selected tab is indicated by "selected" being read out with the tab name, and the screenreader also tells you which tab number you are currently on. In addition, because of the aria-hidden settings (only the non-hidden tab ever has aria-hidden="false" set), the non-hidden content is the only one you can navigate down to, meaning the selected content is easier to find.

Note: If there is anything you explicitly don't want screen readers to read out, you can give them the aria-hidden="true"  attribute.

まとめ

This article has by no means covered all that's available in WAI-ARIA, but it should have given you enough information to understand how to use it, and know some of the most common patterns you will encounter that require it.

参考

 

このモジュール

 

ドキュメントのタグと貢献者

このページの貢献者: piyo-ko, masasnap, Tsuyoshi
最終更新者: piyo-ko,