noAutoFocus
Biomeのlintルールから見るアクセシビリティ
今日はnoAutoFocusです。
なにこれ #
autofocusというグローバル属性を禁止するルールです。
ただし、<dialog>要素の中の要素と、popover属性がついている要素の中の要素には許可されています。
ページが読み込まれたときにautofocusがついている要素があれば、その要素にフォーカスが当たります。ただし、<dialog>要素の中の要素と、popover属性がついている要素の中の要素は、それらが表示されたときにフォーカスが当たります(ref: HTML Standard - The autofocus attribute)。
例えばGoogleのトップページを開いたとき、検索欄に自動でフォーカスが当たります。これはdevtoolsを見てみるとわかりますが、<textarea>要素にautofocus属性が付与されていることによる挙動です。
Googleのトップページにアクセスした人のほとんどは検索欄にて検索をしたいという前提でこれは付与されているし、実際そうだと思います。しかし、このようにほとんどの人が利用するわけではないインタラクティブ要素に自動でフォーカスを当てる場合、ユーザーの予期しない挙動になってしまいます。
最初にスクリーンリーダーユーザーに絞って考えていきます。スクリーンリーダーユーザーは普通、ページの上から順番に読み上げを聞き、必要に応じてランドマークにジャンプしたりしてWebページを閲覧します(と思っています。違ったら教えてください)。しかし、ページにアクセスしたタイミングでautofocus属性のついた要素が存在していて、そこにジャンプしてしまったら、必要なコンテキストを飛ばして読み上げられてしまうことになり、混乱を招きます。
スクリーンリーダーユーザーではないユーザーについても考えてみます。MDNに書いてある通りなのですが、autofocusでフォーカスが当たった要素がビューポート外にある場合に、その要素が見えるようになる位置まで自動でスクロールされてしまう可能性があります。また、モバイルで利用している場合、入力欄にフォーカスすると仮想キーボードが表示されるので、Webページにアクセスした瞬間に仮想キーボードが表示されてしまい、ページの中身も分からないまま何かを入力させられるような体験になる可能性もあります。特にモバイルだと画面が小さいので、最初から仮想キーボードが表示されてしまうのは体験がかなり悪くなると思います。
また、<dialog>要素やpopover属性のついた要素の中の要素については、ページが読み込まれたときではなく、showModal()メソッドやshowPopover()メソッドなどによって表示されたタイミングでフォーカスが当たります。
<dialog>要素のMDNにautofocusについて言及があります。autofocusを指定した要素がないときは、最初のフォーカス可能な要素にフォーカスが自動で当たります。それを別の要素にフォーカスが当たるようにしたいとき、autofocus属性を使います。
このパターンについては最初に言及したように、Biomeのルール的にも許容されています。 ダイアログの初期フォーカス要素については以前WHATWGで議論があったようで、まとめられた記事があります。
また、ダイアログを開いたとき(及び閉じたとき)にどの要素にフォーカスを当てるかについてはAPGにいくつかの例が書かれています。
WCAGの達成基準 #
WCAGの達成基準でいうと、達成基準 2.4.3 フォーカス順序と達成基準 3.2.1 フォーカス時が主に該当すると考えられます。
誤りなく簡潔に説明するのは難しいので、各ページを読んでください。達成基準やそれに関するテクニック内で具体的にautofocusについての言及があるわけではなさそうですが、特に今回は前者の達成基準が関連していそうです。
autofocusを使わないフォーカス制御 #
autofocusは基本的にページを読み込んだタイミングの話なので、Webアプリケーションではあまり使う機会がないかもしれません。
しかし、HTMLElement.focus()などを利用してフォーカス制御をする場合も、フォーカスを強制的に移動させることに変わりはないので注意して使う必要があります。
その他のネタ #
WindowsなのでSafariで今直っているか分からないのですが、<input>要素にautofocusしたときにカーソルがどこに当たるかが、ブラウザ間で異なるというissueがありました。
基本的には入力欄の先頭にカーソルが当たるのですが、2019年時点でSafariだけ入力欄のテキストを全て選択していたようです(selectionStartについて)。
まとめ #
フォーカス制御はちゃんと考えて行いましょう。