Webのアクセシビリティの確認としてスクリーンリーダーを使った動作確認もしてもらうと 「リンクとかボタンしか読まれず、見出しや説明文がスキップされてしまいました」 という報告をされることが時々あります。
これは大抵、スクリーンリーダーを起動して、Tabキーだけを繰り返し押してしまっていることによって起こります。スクリーンリーダーの操作方法を伝えると、読み飛ばしたと思っていたところもちゃんと読みあげてくれたということがほとんです。
アクセシビリティをかなり意識したページであっても、Tabキーだけでスクリーンリーダーを操作しているかぎり、ページの隅々まで読めることはほとんどありません。スクリーンリーダーにはTabキーを押す以外にもいろいろな操作が存在して、それを憶える必要があるわけです。私はアクセシビリティチェックのやり方を説明するときには、必ずその操作方法のうち最低限のものを紹介しているつもりです。
ところが、人によっては「キーボードで操作可能である必要がある」という話で登場するTabキーによる操作と、「スクリーンリーダーで読める必要がある」という話がごっちゃになってしまって、スクリーンリーダーをTabキーだけで操作して、そして読み飛ばしてしまう場所があると思いこんでしまうということが起きているようです。
これはそもそも、スクリーンリーダーを起動していない状態でTabキーを押して操作した経験が乏しく、Tabキーを押したときの挙動を理解できていないことも原因なのではないかと思いました。Tabキーを押したときにどんな動きをするものなのか、スクリーンリーダーを起動したときにその動きに変化があったのかを観察すれば、もうちょっとスクリーンリーダーというものの理解が深まると思います。
ということで、「そもそもTabキーを押したときに何が起きるのか」という話と、「スクリーンリーダーはどう操作するのか」という話を書いて、このあたりを整理してみます。
Tabキーを押したときの挙動
Webページを操作しているときにTabキーを押すと、ページ内のフォーカス可能な要素に、順番に フォーカス が移動します。この状態を、その要素に「フォーカスしている」と言います。
Tabキーによってフォーカスを移動できる要素、以下のようなものです(どれにフォーカスを移動できるかはブラウザやOSや設定によって異なります)
-
tabindex
属性が0
以上の要素 -
href
属性のある<a>
要素(リンク) -
<button>
要素(ボタン) -
<details>
要素またはその中の<summary>
要素(折り畳み -
type="hidden"
以外の<input>
要素(テキスト入力欄、ラジオボタン、チェックボックスなど) -
<select>
要素(セレクトボックス) -
<textarea>
要素(改行可能なテキスト入力欄)……など
つまり tabindex
属性を指定しないかぎり、 クリックしたり、キーボードでの入力を受けつけたりするものにしか、フォーカスは移動しない ようになっています。 <p>
要素などの普通のテキスト要素や、 <h1>
などの見出し要素は、 通常はTabキーによるフォーカスを受け取りません。
また、 inert
属性をつけた要素とその子孫や、disabled
属性を受け付ける要素に disabled
属性をつけた場合には、それらの要素にはフォーカスが移動しません。
フォーカスの仕組みがあることによって、Webページをキーボードのみで操作できるようになります。以下の表に示す操作方法を憶えておけば、普通のWebページはだいたいキーボードのみで操作できるはずです。ぜひ、挙動を確かめてみてください。
操作の種類 | Windowsでのキー操作 | macOSでのキー操作 |
---|---|---|
フォーカスを次に移動 | Tab | Tab |
フォーカスを前に移動 | Shift + Tab | Shift + Tab |
前のページに戻る | Alt + ← | Command + [ |
次のページへ進む | Alt + → | Command + ] |
アドレスバーにフォーカス | Ctrl + L | Command + L |
リンクをクリック | フォーカスした状態でEnter | フォーカスした状態でEnter |
ボタンをクリック | フォーカスした状態でEnterまたはSpace | フォーカスした状態でEnterまたはSpace |
チェックボックスにチェックを入れる | フォーカスした状態でSpace | フォーカスした状態でSpace |
ラジオボタンで別の項目を選択する | フォーカスした状態で↑/↓/←/→ | フォーカスした状態で↑/↓/←/→ |
セレクトボックスで別の項目を選択する | フォーカスした状態で↑/↓ (または、フォーカスした状態でSpaceで選択肢ボックスを開き、↑/↓で選択してEnter) |
フォーカスした状態で↑/↓のあとEnter |
macOSのSafariでは、ボタンやリンクにTabキーでフォーカスを移動できないのがデフォルトの設定になっている
Safariでは、「設定」画面の「詳細」パネル内にある「Tabキーを押したときにWebページ上の各項目を強調表示」のチェックを入れていないと、Tabキーを押したときにボタンやリンクにフォーカスが移動しません(Optionキーを押しながらTabキーを押すと移動できます)。デフォルトではチェックが入っていない状態になっています。
また、macOS版Firefoxでは、「設定(about:preferences
)」内の「タブキーでフォームコントロールおよびリンク間のフォーカスを移動する」にチェックが入ってないと、Safariと同じくボタンやリンクにはTabキーでフォーカスが移動しないようになっています。これはSafariの挙動にあわせて追加されたようで、やはりデフォルトではチェックが入っていません現在はデフォルトでチェックが入らなくなったようです。
スクリーンリーダーを起動していない状態でキーボードで操作できることも重要
こうした、Tabキーによるフォーカス移動を使ったキーボードによる操作も、アクセシビリティを高く保つ上で重要なものです。
なぜなら、障害のあるユーザーで、マウスポインタによる操作が難しいが、キーボードによる操作なら可能という人が存在するからです。たとえば、手や腕に麻痺があって細かい操作ができなかったり、上半身が使えないため足で操作していたり、口に棒を咥えてキーを押していたりするユーザーがいます。
マウスやトラックパッドは、水平な場所でマウスという物体を動かしたり、板状のトラックパッドを指先でなぞったりと、複雑だったり繊細だったりな動きを要求します。キーボードであれば、ただボタンを押すだけの単純な動きさえできればいいため、足や口など指以外で操作したり、代替のハードウェアを作ったりしやすい利点があります。
もちろん、キーボードで操作できることは、なるべくキーボードのホームポジションから手を動かさず効率的に操作したいだけのユーザーにとっても重要なことです。
そして、スクリーンリーダーに対してもキーボードで操作できることが重要です。画面を見ることができなくてスクリーンリーダーを使うユーザーは、マウスポインタの位置がわからないとため、マウスポインタによる操作ができません。
tabindex
属性の使い所
tabindex
属性は、もともと tabindex="1"
の要素から順番にTabキーで移動していけるように用意された属性です。つまり、Tabキーを押していくことで tabindex="1"
の要素 → tabindex="2"
の要素→ tabindex="3"
の要素……というふうにTabキー押下時の移動順をコントロールするものです。
しかし、現在では tabindex
属性の値は 0
か -1
のみに制限する ことがベストプラクティスとして知られています 。
tabindex
属性に 1
以上の数値を入れて、Tabキーで移動する順序を制御しようとすると、以下のような問題が発生します。
-
tabindex
属性の指定漏れがあった場合に、その要素はスキップされ、順番が最後になってしまう - Tabキーを併用するスクリーンリーダー利用者は、Tabキーによる移動順がスクリーンリーダの読み上げ順序と一致しないことで混乱してしまう
- ページの途中にコンテンツを挿入する必要が発生した場合に、
tabindex
の値をすべて変えていくのは大変
以下のようなときに -1
または 0
のみを使用します。
- Tabキーでフォーカスできなくて良いが、JavaScriptによる制御でフォーカスを移動させることがある要素には、
tabindex="-1"
を指定します - 本来ならTabキーでフォーカスできる要素に、Tabキーでフォーカスさせないようにするには
tabindex="-1"
を指定します(これをやる場合はキーボードで操作できる代替手段を提供する必要があります) - 本来ならTabキーでフォーカスできない要素に、Tabキーでフォーカスが移動するようにするためには
tabindex="0"
を指定します
これらは読んだだけでは、具体的にどんなときに tabindex
を使うべきかイメージできないと思います。わたしの共著書の「Webアプリケーションアクセシビリティ」には、 tabindex
を使う事例がいくつも紹介されているので、詳しくはそちらを読んでいただければと思います。
スクリーンリーダーをTabキーで操作して、スクリーンリーダーで読めない場所があると勘違いしてしまい、あらゆるものに tabindex="0"
を付けてしまう人がたまに現れます。これをやると、スクリーンリーダーのユーザーではないがキーボードだけで操作したい人にとっては、無駄なものにひたすらフォーカスが当たりつづける迷惑なページになってしまいます。
スクリーンリーダーのカーソルは、フォーカスとは別
ここまで書いたとおり、Tabキーによる操作では多くの要素にフォーカスが移動しません。そういった場所をスクリーンリーダーで読んでいくにはどうすれば良いのでしょうか。
実は、多くのスクリーンリーダーで フォーカスとは別に、スクリーンリーダー専用のカーソルが存在する 作りになっています。
多くのスクリーンリーダーは、起動すると、いま読み上げている場所に枠線が表示されるようになっている、またはそういったものを表示する機能が提供されています。これを指して「フォーカス」と呼んでいる例もあります。しかし、これはフォーカスとは別のものとして理解するべきものです。macOS VoiceOverでは「VoiceOverカーソル」と呼んでいるようなので、ここでは「スクリーンリーダーのカーソル」という言い方をします。
(表示している画面は Wikipedia「スクリーンリーダー」)
スクリーンリーダーのカーソルは、フォーカスが移動するとそれに追従します。そのため、Tabキーを押すとスクリーンリーダーのカーソルも移動し、フォーカスしている場所が読み上げられます。
ところがスクリーンリーダーは、Tabキーでフォーカスしない場所も読み上げなければなりません。画面を視覚的に見られない人にとっては、スクリーンリーダーが読み上げる情報がその画面のすべてだからです。そこで、スクリーンリーダーはフォーカスとは別の独自のカーソルをもち、きちんとページの隅々まで読めるように作られています。
NVDAとmacOS VoiceOverでは、以下のような操作でスクリーンリーダーのカーソルを移動できます。
操作 | NVDA | macOS VoiceOver |
---|---|---|
カーソルを進める | ↓ | VO + → |
カーソルを戻す | ↑ | VO + ← |
(VOはVoiceOverキーのことで、デフォルトの設定ではCapsLockキーまたはControlキーとOptionキーの同時押しがVoiceOverキーになっています)
スクリーンリーダーのカーソルが移動すると、NVDAでは1行ずつだったり、VoiceOverでは要素やテキストノードの単位だったりで、少しずつ読み進めていけるようになっています。また、スクリーンリーダーのカーソルがフォーカス可能な要素に到達すると、こんどはフォーカスのほうがスクリーンリーダーのカーソルに追従するような挙動をすることもあります。
まとめ
この記事に書きたかったのは、以下の2点です。
- Tabキーを押したときの挙動はスクリーンリーダーを起動していてもしていなくても同じで、特定の要素にしかフォーカスは移動しません
- スクリーンリーダーは、フォーカスと独立したカーソルを持ち、スクリーンリーダー独自の操作方法で操作する必要があります
これらは、当事者になったつもりで練習する、すなわち「マウスが操作できなくなったつもりで、マウスポインタを使わずに操作してみる」とか、「目が見えなくなったつもりで、スクリーンリーダーでいろんなページを読んでみる」みたいなことをすると、自然と理解できたり、またはどうやれば上手くできるものなのか気になって調べたくなるものだと思います。ところが、アクセシビリティチェックリストを渡されて「これをチェックしてください」と言われただけだと、そういう自発的に調べたり理解したりする動きになりにくいのかもしれません。どうか、「言われたからやる」ではなく、「あらゆる人に届けるためにやる」つもりで、アクセシビリティに取り組んでもらえたらな、と思います。