なぜ「タブ」はスクリーンリーダーで読めない? タブをアクセシブルにする
ユーザーテストの結果、いくつかの問題点が明らかになりました。問題点の多くは、ラベルの文言の変更、代替テキストの調整といった微修正レベルで対応できるものでしたが、中に一つ大物案件がありました。それが、タブの問題です。
何が問題かおさらい
ユーザーテストでは、スクリーンリーダーでタブを読む際に問題が起こりました(ユーザーテストの詳細は、第4回をご覧ください)。問題となった動きをおさらいすると、次の通りです。
- 「料金表」というタブにフォーカスを合わせることはできた(「料金表」というリンクとして伝わる)
- リンクを選択すると、見た目の上では下部のコンテンツが切り替わり、料金表が表示される
- しかし、スクリーンリーダーでは切り替わったことが通知されず、リンクを選択しても何も起きないように感じられる
- 何かが切り替わったと予想できても、切り替わったコンテンツに移動することが困難
問題はスクリーンリーダーで「タブ」がうまく扱えないこと
この問題を一言でまとめると、スクリーンリーダーで「タブ」がうまく扱えていない、ということになります。なぜこのタブは、スクリーンリーダーでうまく扱えないのでしょうか。
実は、Webで使われているタブの多くは、スクリーンリーダーでうまく扱うことができません。その原因は、そもそもHTMLが「タブ」というインターフェイスをサポートしていないことにあります。
「テキスト入力欄」はHTMLでサポートされている
HTMLでは、「リンク」はもちろんのこと、「テキスト入力欄」や「ラジオボタン」といったフォーム部品も用意されています。HTMLにこのようなフォーム部品を配置すると、見た目や動作がきちんと再現されるのはもちろんのこと、気づかれにくい細かい機能も提供されます。
たとえばテキスト入力欄の場合、マウスでクリックして文字を入力できるようになっていますが、そのほかにも以下のような機能があります。
- キーボード操作でフォーカスを当てることができる
- 入力欄に文字をペーストすることができる
- 入力欄の文字をコピーすることができる
- スクリーンリーダーでは、テキスト入力欄であることを通知してくれる
- スクリーンリーダーでは、対応するラベルが指定されていれば読み上げられる
こうしてみると、意外と多くの機能があることがわかります。しかし作り手は通常、これを意識する必要はありません。HTMLのinput要素を配置すれば、ブラウザが自動的にこれらの機能を提供してくれるのです。
このように、HTMLがもともとサポートしているフォーム部品の場合、作り手が普段意識していないような、さまざまな機能がブラウザによって提供されます。そのため、作り手が特別なことをしなくても、一定のアクセシビリティが確保されるのです。
「タブ」はHTMLでサポートされていない
世のWebページでは、タブらしい見た目のインターフェイスがたくさんあります。よく使われる機能のように思えますが、実は残念ながら、HTMLには「タブ」に相当する部品は用意されていません。
Web上のタブらしきものは、実際にはタブではない要素を使って実現されています。その上で、CSSやJavaScriptを駆使することで、見た目と動きをタブ風にしているにすぎないのです。
この場合、見た目の上では問題なく動作しても、作り手が意識していない機能が抜けてしまうことがあります。Web上のタブではなく、OSが提供するタブには、実は以下のような機能があります。
- キーボード操作でタブにフォーカスを当てることができる
- スクリーンリーダーでは、タブであることを通知してくれる
- タブにフォーカス後、キーボードの左右キーでタブを切り替えることができる
- タブ切り替え後、切り替わった内容に移動できる
Web上でタブを再現しても、これらの機能は自動的には提供されません。実装者が意図的に実装しなければならないのです。つまり、意識してアクセシビリティを担保しない限り、タブをスクリーンリーダーで読むことは難しいと言えます。弁護士ドットコムのサイトにあったタブも同様で、特別な対応が行われていないものでした。
対応する目的を明確にする
さて、それではこのタブをスクリーンリーダーで読めるようにしていきましょう。
と、言いたいところですが、その前に、この対応を行う目的や要件を整理しておきましょう。
今回の問題は、タブを使って表現されている情報があり、スクリーンリーダーで読むことが難しいということでした。ここで、「タブをスクリーンリーダーで操作できるようにする」という目的を設定するのは、間違いではありません。しかしそうすると、タブの実装方法だけに注目することになってしまい、他の選択肢が視野に入らなくなってしまいます。
冷静に考えると、必ずしもタブにこだわる必要はないはずです。ここで最終的に達成しなければならないことは、「スクリーンリーダーのユーザーにも情報が伝わるようにする」ということです。
△ 「タブをスクリーンリーダーで操作できるようにする」
○ 「スクリーンリーダーのユーザーにも情報が伝わるようにする」
複数ある対応方法から最適なものを選択する
スクリーンリーダーのユーザーにも情報が伝わるようにする方法は、一つではありません。今回の件に限らず、アクセシビリティの問題を解決する方法は複数あるのが普通です。
W3Cは、アクセシビリティガイドラインWCAG 2.0の達成基準を達成するための方法をまとめて「WCAG 2.0 達成方法集」という文書にしていますが、ここでも、一つの達成基準に対して複数の達成方法が挙げられています。
対応方針を考える際には、複数の解決策があることを意識した上で、どれを採用するのかを検討すると良いでしょう。今回の例で言えば、たとえば以下のような選択肢が考えられます。
スクリーンリーダーでも「タブ」として操作可能にする
OSが提供するタブの機能をWebで再現する。基本的には望ましい対応だが、タブ操作に慣れていないユーザーは逆に混乱する可能性もある。また、さまざまな実装を行う技術が必要で、一定のコストがかかる。タブをやめて、中身を全て縦積みにする
対応させるのに特に技術力は必要ない。スクリーンリーダー以外のユーザーも見やすくなる可能性がある。しかし、画面のデザインが大幅に変わることになるため、かなり大掛かりな改修になる。デザイン変更の予定があるなら検討の余地あり。スクリーンリーダー用の代替ページを用意する
スクリーンリーダーの利用者を別ページに誘導する案。一見簡単そうだが、複数ページをメンテナンスし続ける必要があり運用コストが高い。既存ページに手を入れる必要がないように見えるが、実は誘導の方法を検討する必要があるため、既存ページにも何らか改修が入ることになる。導入コストも高い。タブが「リンク」として読まれるまま、タブの内容にアクセスできるようにする
スクリーンリーダーに対し、タブをタブとして通知させるのではなく、ページ内リンクとして見せる案。現状ではすでにリンクのように見えているため、リンクを辿った時に何も起きないという問題だけ解決すれば良く、導入コストが低い。ただし、タブであることは伝わらない。
これら以外にも、対応するレベルによってさらに施策は異なります。また、実際に実装してみてから軌道修正が必要になることもあるため、まずは必要最低限の対応を実装してみるとよいでしょう。
今回の対応方針 :「リンク」と通知されれば良し
今回は、タブが「リンク」として読まれるまま、タブの内容にアクセスできるようにする方針を採用しました。
この対応では、スクリーンリーダーのユーザーはタブを単なるリンクとして認識し、ページ内リンクをたどってタブ内のコンテンツにたどり着くことになります。この方針であっても、目的として掲げた「スクリーンリーダーのユーザーにも情報が伝わるようにする」という要件は問題なく満たせます。
あえて問題点を挙げるなら、それがタブであることを知ることができない、という点があります。たとえば、ヘルプデスクに問い合わせした際に、「タブを選択してください」という指示をされても、その意図がうまく伝わらないことがあるかもしれません。とはいえ、今回それは大きな問題ではないと考え、タブを「タブ」としては見せず、タブの中身が読める「リンク」と通知されればよい、と判断しました。
なお、この判断が常に正しいというわけではありません。ツール寄りのWebアプリケーションなどでは、タブがタブとして認識されないと困るということもあるでしょう。そのような場合は、他の方針のほうが良いかもしれません。
実装とテストを繰り返す
全体の方針が決まったら、実装の方針を考えて実装してみます。具体的な実装方法については、[コーディングWebアクセシビリティ - WAI-ARIAで実現するマルチデバイス環境のWebアプリケーション]が参考になるでしょう。
ここでは、既存のJavaScriptに以下のような処理を追加することにしました。
- タブを選択した時に表示されるコンテンツの見出しに tabindex="-1" をつけて、フォーカスを可能にする
- タブが選択されたら focus() メソッドを呼び、対応する見出しにフォーカスを移す
これを簡単に実装して、実際にスクリーンリーダーでアクセスしてみると、問題なく読まれるようになりました。
うまく実装できた、しかし問題発生?
しかし、ひとつ問題が。タブを選択した際、移動した先の見出しにフォーカスが移るのですが、そこに枠が表示されるようになったのです。キーボード操作時だけでなく、タブをマウスでクリックした際にも表示されます。動作には支障ないのですが、かなり目立つ表示で、既存の操作感が変わってきてしまいます。
マウス操作の際は、このようにフォーカスが見える必要はありません。そこで、キーボード操作時だけこの動作をするようにしてみました。具体的には、タブが押された際にキーボードのキーが押されていたかどうかを判定し、キーが押されていたらキーボード操作とみなしてフォーカスが見えるようになる、という実装です。
しかし、検証してみると、どうもうまくいきません。スクリーンリーダーを起動しない状態では意図どおりに動作するのですが、スクリーンリーダーを起動するとうまく動作しない、という結果になりました。
スクリーンリーダーにキー操作を奪われていた
問題を詳しくみていくと、原因がスクリーンリーダーの挙動にあることがわかりました。
スクリーンリーダーが動作していない場合、ブラウザ上でユーザーがキー操作をすれば、そのことがブラウザに伝わり、キー操作を行ったというイベントが発生し、対応するスクリプトなどが動作します。
しかし、スクリーンリーダーが動作していると、ユーザーのキー操作はまずスクリーンリーダーに伝わります。たとえば、ユーザーが「H」のキーを押すと、これはまずスクリーンリーダーに伝わり、「次の見出しに飛ぶ」という機能が実行されます。そしてブラウザには、「H」キーが押されたということは伝わらないのです。
もっとも、これではフォーム入力などもできなくなるため、スクリーンリーダーには、キー操作を直接ブラウザに伝えるモードも用意されています。たとえばNVDAでは、キー操作をいったんNVDAが受け取って処理をしする「ブラウズモード」と、キー操作を直接ブラウザに渡す「フォーカスモード」があります。通常はブラウズモードで動作しますが、入力欄にフォーカスが当たると自動でフォーカスモードに切り替わり、文字などの入力が可能になるのです(手動でモードを切り替えることも可能です)。
フォーカスモードにすればブラウザにキー操作が伝わりますが、通常時はブラウズモードになっており、このモードではキー操作関連のイベントが発生しません。例外的に、Enterキーを押した場合にはclickイベントが発生するのですが、押されたキーの情報はブラウザ側に伝わっておらず、キーボード操作であるという判定に失敗してしまうのです。
問題が起きたときも、目的に戻って考えれば良い
結局、「キーボード操作時のみ反応させる」という方向性を諦め、キーボード/マウス問わず常にフォーカスを移しつつ、フォーカス移動した際にフォーカス枠を非表示にするように変更しました。
一見問題ないのですが、実は、この対応にはひとつ問題があります。フォーカス枠は、現在のフォーカス位置を示す重要な情報です。これが見えなくなると、目で見てキーボード操作するユーザーは、今どこにフォーカスがあるのかわからなくなってしまいます。
今回の例では、「スクリーンリーダーのユーザーにも情報が伝わるようにする」ということが目的でしたが、スクリーンリーダー以外で使えなくなってしまうようなら、それも問題です。つまり、実際には以下の2点を満たす必要があります。
- スクリーンリーダーのユーザーに情報が伝わる
- スクリーンリーダー以外のユーザーにも、依然として情報が伝わる
とはいえ今回の例では、フォーカスが見えなくなるといっても一時的なものであり、その後フォーカスを移動させれば見えるようになるため、情報が伝わらないということはないと判断しました。
時にはこのように、完璧な対応が難しいこともあります。技術的な理由で対応できないこともあれば、費用や期間の問題が出てくることもあるでしょう。常に目的を意識し、そこに戻って考えてみましょう。
また、判断が難しい場合には、ユーザーテストで判断する方法もあります。テスト的に実装した段階で、当事者のユーザーを呼んでテストを行うのです。このテストで問題なく読めているようなら、ひとまず問題ないと判断して良いでしょう。
次回 視覚障害は全盲だけではない
ここまでで、全盲の方によるユーザーテストの実施と、その結果の反映までを一通り見てきました。
しかし、これで終わりではありません。さまざまな環境のユーザーにアクセスできるようになったと言うには、まだまだ足りないものがたくさんあります。たとえば、視覚障害は全盲だけではないのです。
次回は、弱視(ロービジョン)の方によるユーザーテストをご紹介したいと思います。
ソーシャルもやってます!