モーダルダイアログを視覚表現だけで終わらせない - Web Accessibility Advent Calendar 2013

Web Accessibility Advent Calendar 2013 初日です。
http://www.adventar.org/calendars/64

neotagです。初日なのに記事公開が遅れてしまいました。
しょっぱなから出鼻をくじいてしまい大変申し訳ありません。(土下座)

追記 2013/12/06

この記事の補足になる記事を @milk54 さんが書いてくださいました。
リニューアルして情報が得られなくなったというサイトを調べてみた
追記ここまで


JavaScript による視覚表現が盛んになってから当たり前に使われるようになったモーダルダイアログについてです。
このモーダルダイアログ、ちょっとした情報を追加で表示する際に大変便利なのですが、見た目だけ実装すると思わぬ罠があります。

普通に組んだ場合

Library など使わずに普通に JavaScript を書いた場合です。(最近の Library はこの問題を解決済みなものが多いのでそもそも考慮不要な場合も多いです。)

デモ: http://jsdo.it/neotag.twit/sBK5
※解説に必要なダイアログの表示部分のみです。閉じるとかアニメーションとか気の利いた物はありません orz

問題点

このデモでは単にダイアログを表示しているだけなので、何を表示したのかユーザーエージェント側ではわからない状態になっています。
すなわち音声読み上げブラウザなどに対して何が起きたのか一切伝えられていない状態です。リンクを押しても反応がなく、次に何をしたらいいのか分からず迷子になってしまいますね。

解決策

フォーカスをあてる。以上。

表示したダイアログにフォーカスをあててあげましょう。これにより、読み上げ位置がダイアログに移動し迷わずに操作を継続できるようになります。
jQuery を使える環境であれば下記の2ステップで解決可能です。

  • dialog の要素に tabindex="0" を付与する *1 *2
  • dialog 表示後に .focus() をする。 *3

デモ: http://jsdo.it/neotag.twit/uDAb

html:

<div id="dialog" tabindex="0">

JavaScript:

            target.focus();

OSXChrome などで見るとダイアログの周りに薄い水色の outline が付いているのが分かるかと思います。
要素にフォーカスがあたっているときに出るブラウザデフォルトの装飾ですね。(textarea とかで良く見るやつ)
outline が不要であれば css で outline: none にしてあげてください。ただし、全称セレクタなどでまとめて指定するのは避けましょう。input や textarea などブラウザデフォルトの挙動は極力残すべきです。*4


「閉じる」にも注意

閉じる機能の実装をしていませんが、これも単に閉じただけでは読み上げ位置が元の場所に戻りません。
モーダルダイアログを開く際に押したリンクを記憶しておいてモーダルダイアログを閉じたらそのリンクへフォーカスを戻すなどの工夫が必要ですね。

まとめ

モーダルダイアログを例に、視覚に頼ったUIで迷子になる問題とその解決方法を紹介しました。
とくに厳密なモーダルダイアログはダイアログ以外の操作を受け付けないため迷子どころか落とし穴に入った状態になる危険性すらあります。
便利どころかアクセス不能ですね。アクセシビリティゼロです。
これはユーザビリティをあげようと思って知らないうちにアクセシビリティを落としている好例だと思っています。

代替テキストによるアクセシビリティの向上だけでなく、各種操作が視覚表現に頼ったものになっていないか少しでも意識できるようになればと思い書きました。

今回は手軽な解決方法の紹介でしたが、関連技術として WAI-ARIA などのしっかりした仕様もあります。この Web Accessibility Advent Calendar 2013 でも出てくると思いますので楽しみにしています。


Web Accessibility Advent Calendar 2013 の2日目は、ChibaReimi@rechiba3さんです。よろしくお願いします!

*1:tabindex に 1 以上の数字を与えるとタブ移動の順序が変わり、管理できなくなると動作が破綻します。明確な理由がないかぎり0にして順序はユーザーエージェントに任せるのが無難です。

*2: 実はHTML4.01だとdivにtabindexふれないんですよね。HTML5万歳。(謎

*3: 表示前に .focus() することはできないので必ず表示後に行いましょう。

*4: モーダルダイアログは表示そのものが視覚的な誘導になっているので outline 不要な場合が多いですが、input や textarea などは視覚的な誘導を残しておかないとどこにカーソルがあたってるか分からなくなりますよね。