フォーカス インジケーター(多くの場合「フォーカス リング」で示されます)は、ページ上で現在フォーカスされている要素を示します。マウスを使用できないユーザーにとって、このインジケーターはマウスカーソルの代用として機能するため、非常に重要です。
ブラウザのデフォルトのフォーカス インジケーターがデザインと競合する場合は、CSS を使用してスタイルを変更できます。ただし、キーボード ユーザーを念頭に置くようにしてください。
:focus
を使用してフォーカス インジケーターを常に表示する
:focus
疑似クラスは、入力デバイス(マウス、キーボード、タッチペンなど)やフォーカスに使用した方法に関係なく、要素にフォーカスが当てられるたびに適用されます。たとえば、以下の <div>
には tabindex
があり、フォーカス可能になっています。また、:focus
状態のカスタム スタイルもあります。
div[tabindex="0"]:focus {
outline: 4px dashed orange;
}
マウスでクリックするか、キーボードで Tab キーを押して移動するかにかかわらず、<div>
は常に同じ外観になります。
残念ながら、ブラウザによってフォーカスの適用方法が異なる場合があります。要素がフォーカスを受け取るかどうかは、ブラウザとオペレーティング システムによって異なります。
たとえば、次の <button>
には、:focus
状態のカスタム スタイルもあります。
button:focus {
outline: 4px dashed orange;
}
macOS の Chrome で <button>
をマウスでクリックすると、カスタム フォーカス スタイルが表示されます。ただし、macOS の Safari で <button>
をクリックしても、カスタム フォーカス スタイルは表示されません。これは、Safari では要素をクリックしてもフォーカスが要素に移動しないためです。
フォーカスの動作は一定ではないため、フォーカス スタイルがユーザーにとって許容できるものであることを確認するには、さまざまなデバイスでテストを行う必要があります。
:focus-visible
を使用してフォーカス インジケーターを選択的に表示する
新しい :focus-visible
疑似クラスは、要素がフォーカスを受け取るたびに適用され、ブラウザがヒューリスティクスによってフォーカス インジケーターを表示することがユーザーにとって有益であると判断します。特に、直近のユーザー操作がキーボード経由で行われ、キー入力にメタキー、ALT
/ OPTION
、または CONTROL
キーが含まれていない場合、:focus-visible
が一致します。
以下の例のボタンは、フォーカス インジケーターを選択的に表示します。マウスでクリックした場合と、最初にキーボードで Tab キーで移動した場合の結果は異なります。
button:focus-visible {
outline: 4px dashed orange;
}
:focus-within
を使用してフォーカスされている要素の親にスタイルを適用する
:focus-within
疑似クラスは、要素自体がフォーカスを受け取ったとき、またはその要素内の別の要素がフォーカスを受け取ったときに要素に適用されます。
ページの一部をハイライト表示して、その部分にユーザーの注意を引くことができます。たとえば、次のフォームは、フォーム自体が選択されたときと、いずれかのラジオボタンが選択されたときの両方でフォーカスを受け取ります。
form:focus-within {
background: #ffecb3;
}
フォーカス インジケーターを表示するタイミング
モバイル デバイスを使用しているときにこのコントロールをクリックしたら、キーボードが表示されることを期待するかどうかを自問するのが良い判断基準です。
答えが「はい」の場合、フォーカスに使用した入力デバイスに関係なく、コントロールは常にフォーカス インジケーターを表示する必要があります。<input type="text">
要素はその良い例です。入力要素が最初にフォーカスを取得した方法に関係なく、ユーザーはキーボードを介して要素に入力を送信する必要があります。そのため、フォーカス インジケーターを常に表示することをおすすめします。
答えが「いいえ」の場合、コントロールはフォーカス インジケーターを必要に応じて表示できます。<button>
要素はその好例です。ユーザーがマウスまたはタッチ スクリーンでクリックすると、アクションは完了するため、フォーカス インジケーターは不要な場合があります。ただし、ユーザーがキーボードで移動している場合は、フォーカス インジケーターを表示して、ユーザーが ENTER
キーまたは SPACE
キーを使用してコントロールをクリックするかどうかを決定できるようにすると便利です。
outline: none
を避ける
正直なところ、ブラウザがフォーカス インジケーターを描画するタイミングを決定する方法は非常に混乱しています。CSS で <button>
要素の外観を変更するか、要素に tabindex
を指定すると、ブラウザのデフォルトのフォーカス リングの動作が開始されます。
非常に一般的なアンチパターンは、次のような CSS を使用してフォーカス インジケーターを削除することです。
/* Don't do this!!! */
:focus {
outline: none;
}
この問題を回避するには、:focus
と :focus-visible
ポリフィルを組み合わせて使用することをおすすめします。以下の最初のコードブロックは、ポリフィルの仕組みを示しています。その下にあるサンプルアプリは、ポリフィルを使用してボタンのフォーカス インジケーターを変更する例を示しています。
/*
This will hide the focus indicator if the element receives focus via the
mouse, but it will still show up on keyboard focus.
*/
.js-focus-visible :focus:not(.focus-visible) {
outline: none;
}
/*
Optionally: Define a strong focus indicator for keyboard focus.
If you choose to skip this step, then the browser's default focus
indicator will be displayed instead.
*/
.js-focus-visible .focus-visible {
…
}