ページ内アンカーへのキーボード操作でのアクセシビリティ (ブラウザ側の機能改善)

この記事は、Web アクセシビリティ Advent Calendar 2020 の7日目の記事です。


リンク (ハイパーリンク) はウェブをウェブたらしめる、根幹的な機能です。一般的にリンクは、今いるページとは別のページに遷移するものですが、ページ内の特定のセクション (ページ内アンカー) に遷移するリンクもあります。たとえば、ページの冒頭に目次を設けておき、目次の項目のいずれかをクリックまたはタップすると、該当するセクションにジャンプできる、という具合です。

今から5年ほど前になりますが、「ページ内アンカーについて考える」という記事を書き、このページ内アンカーにまつわるユーザビリティの問題について考察したことがあるのですが、その際、キーボード操作でのアクセシビリティ (フォーカス制御) の問題についても言及していました。以下、当時記載していた内容です。

ページ内アンカーはまた、キーボード操作のにおいても問題があります。ページ内アンカーに遷移するリンクに [Tab] キーでフォーカスを当てて、[Enter] キーを押すと、ブラウザウィンドウ内にはそのアンカーが埋め込まれたセクションが (一見問題なく) 表示されます。ところが、そこからさらに [Tab] キーを押した場合、ユーザーとしては「遷移後のアンカーを基点に、その次のフォーカス可能な要素にフォーカスが移る」ことを期待するものですが、実際そのように挙動するのは Firefox くらいで、多くのブラウザは以下のような挙動をするのです。

  • OS X Safari では、ページ内アンカーに遷移する前のリンクを起点に、その次のフォーカス可能な要素にフォーカスが移る。
  • Chrome や Internet Explorer では、当該ページのいちばん上のフォーカス可能な要素にフォーカスが移る (強制的に「ふりだしに戻る」状態になる)。

これでは、キーボード操作に依存せざるを得ないユーザー (怪我や上肢障害などでマウスが使えない人) にとって大きなフラストレーションになるだけでなく、最悪の場合、コンテキストを見失ってしまうことにもつながります。ページ内アンカーを採用する際には、このようなフォーカス制御についても、考慮に入れる必要があります。

それから5年の歳月が流れましたが、嬉しいことにいつの間にか、上述のキーボード操作でのアクセシビリティ (フォーカス制御) の問題が、主だったブラウザでひととおり解消されていることが確認できました。(今更ながら気づいた、という次第ですが ...)

検証方法と結果

See the Pen ページ内アンカーへのリンク by @caztcha (@caztcha) on CodePen.

検証用に、上のようなサンプルページを作りました。単に HTML だけを用いて、 リンク元となる <a> 要素の href 属性に、リンク先の id 属性値と同じフラグメント識別子 (†) を入れただけの、簡単なものです (Full Page View はこちら)。

† 「フラグメント識別子」とは、ページ内のある特定の箇所 (アンカー) を識別し指定するための、#に続く文字列のことです。

このページを、以下のブラウザで開き、それぞれ、キーボード操作を試してみました。

いずれのブラウザでも、ページ内アンカーに遷移するリンク (ページ冒頭にあるリストのリンク) に [Tab] キーでフォーカスを当てて [Enter] キーを押すと、該当する項目のセクション (見出し) にジャンプしますが、そこからさらに [Tab] キーを押すと、そのセクション以下にあるフォーカス可能な要素 (「ページの先頭に戻る」リンク) にフォーカスが移りました。

こうして見ると、ページ内アンカーへのキーボード操作を用いたアクセシビリティは、JavaScript を用いて特別なフォーカス制御の仕組みを実装しなくても、HTML のみで問題なく担保できており、各ブラウザにおいて、ユーザーのメンタルモデルと合致した適切な挙動をするようになっていると言ってよいでしょう。こうしたブラウザ側の機能改善は、当然期待されることとは言え、とてもありがたいものです。

フラグメント識別子の記述は確実に

ただし一点、注意が必要です。それは、リンク元となる <a> 要素の href 属性と、リンク先のアンカー要素の id 属性の両方に、同一のフラグメント識別子を確実に明記する必要があるということです。

時折、ページ先頭に戻るリンクで、フラグメント識別子を明記しない例を見かけますが (<a href="#"> という具合)、これだと一見ページ先頭にジャンプしているように見えるものの、その状態で [Tab] キーを押すと、ユーザーの予期しないフォーカス移動をしてしまいます。上のサンプルページでは、「項目B」セクションの「ページの先頭に戻る」リンクを敢えてこのアンチパターンで実装していますので、挙動の違いを確かめてみてください。

PC におけるキーボード操作だけでなく、スマートフォンやタブレットでも、スクリーンリーダー併用時に、同様の問題が生じます。たとえば、iOS Safari で VoiceOver を起動した状態で、フラグメント識別子が明記されていないリンク (上のサンプルでは、「項目B」セクションの「ページの先頭に戻る」リンク) をダブルタップすると、画面表示上は正常にジャンプしているように見えるものの、その状態で右フリック操作をすると、予期しないフォーカス移動をします。

(2020年12月8日追記)
WHATWG (Web Hypertext Application Technology Working Group) の「HTML Living Standard」によると、仕様上は <a href="#"> と記述すること自体は誤りではなく、このようにフラグメント識別子が空の場合、そのリンク先は暗黙的にドキュメントの先頭を示すと規定されています。また、<a href="#top"> と記述されている場合も、そのリンク先はドキュメントの先頭を示すと規定されています。(参考 : HTML Living Standard (7.10 Browsing the web) の「The indicated part of the document」の項)

ただし現状ではブラウザ側の実装が追いついておらず、<a href="#"> または <a href="#top"> と記述するだけでは、フォーカスの起点をページの先頭に戻す挙動になりません。キーボード操作でのアクセシビリティを確実なものにするには、フラグメント識別子をリンク元 (<a> 要素の href 属性) およびリンク先 (該当するアンカー要素の id 属性) に、それぞれ明記するのが現実的と言えます。