フォーカス インジケーター(多くの場合、フォーカス リングで示されます)は、ページ上でフォーカスされている要素を特定します。マウスを使用できないユーザーや使用したくないユーザーにとって、このインジケーターはマウスカーソルの代わりとなるため、非常に重要です。
ブラウザのデフォルトのフォーカス インジケーターがデザインと競合する場合は、CSS を使用してスタイルを変更できます。ユーザーのことを常に念頭に置いてください。
:focus を使用してフォーカス インジケーターを常に表示する
:focus 疑似クラスは、使用中の入力方法やデバイス(マウス、キーボード、タッチペンなど)に関係なく、フォーカスされている要素に適用されます。
たとえば、次の <div> には、フォーカス可能にする tabindex と、:focus 状態のカスタム スタイルがあります。
div[tabindex="0"]:focus {
outline: 4px dashed orange;
}
どのデバイスを使用しても、フォーカス時の <div> の見た目は同じです。
残念ながら、ブラウザによってフォーカスの適用方法が異なる場合があります。要素がフォーカスを受け取るかどうかは、ブラウザとオペレーティング システムによって異なる場合があります。
たとえば、次の <button> には :focus 状態のカスタム CSS があります。
button:focus {
outline: 4px dashed orange;
}
macOS 版 Chrome でマウスを使用して <button> をクリックすると、カスタム フォーカス スタイルが表示されます。ただし、macOS の Safari で <button> をクリックした場合は、カスタム フォーカス スタイルは表示されません。これは、Safari では要素をクリックしてもフォーカスが取得されないためです。
フォーカスの動作に一貫性がない。さまざまなデバイスと入力でページをテストし、フォーカス スタイルがユーザーにとって許容できるものになっていることを確認します。
:focus-visible を使用してフォーカス インジケーターを選択的に表示する
:focus-visible 疑似クラスは、要素がフォーカスを受け取り、ブラウザが(ヒューリスティックを使用して)フォーカス インジケーターを表示することがユーザーにとって有益であると判断した場合に適用されます。特に、最新のユーザー操作がキーボードで行われ、キー押下に Meta、ALT、OPTION、CONTROL キーが含まれていない場合、:focus-visible は一致します。
次の例のボタンは、フォーカス インジケーターを選択的に表示します。マウスでクリックした場合と、キーボードでタブ移動してからクリックした場合では、結果が異なります。
button:focus-visible {
outline: 4px dashed orange;
}
:focus-within を使用して、フォーカスされている要素の親のスタイルを設定する
:focus-within 疑似クラスは、要素自体がフォーカスを受け取ったとき、または子要素がフォーカスを受け取ったときに要素に適用されます。ページ内の領域をハイライト表示して、ユーザーの注意をその領域に引きつけるために使用できます。
たとえば、フォーム自体が選択された場合と、フォームのラジオボタンのいずれかが選択された場合の両方で、フォームにフォーカスが移動します。
form:focus-within {
background: #ffecb3;
}
フォーカス インジケーターを表示するタイミング
「モバイル デバイスを使用しているときにこのコントロールをクリックしたら、キーボードが表示されることを期待するか?」と自問してみるのがよいでしょう。
- 該当する場合: 入力デバイスに関係なく、コントロールには常にフォーカス インジケーターが表示されるべきです。たとえば、
<input type="text">要素はほぼ常にこのようになっています。入力要素がフォーカスされた方法に関係なく、ユーザーはキーボードで要素に入力を送信する必要があります。 - If no: コントロールは、フォーカス インジケーターを選択的に表示することを選択できます。たとえば、ユーザーがマウスまたはタッチスクリーンで
<button>をクリックすると、アクションが完了します。フォーカス インジケーターは不要な場合があります。ただし、ユーザーがキーボードで操作している場合は、フォーカス インジケーターを表示すると、ユーザーが ENTER または SPACE でコントロールを有効にするかどうかを判断するのに役立ちます。
outline: none を避ける
ブラウザがフォーカス インジケーターを描画するタイミングを決定する方法は、率直に言って非常にわかりにくいものです。CSS で <button> 要素の外観を変更したり、要素に tabindex を指定したりすると、ブラウザのデフォルトのフォーカス リングの動作が開始されます。
開発者が CSS を使用してフォーカス インジケーターを削除することがあります。
/* Don't do this!!! */
:focus {
outline: none;
}
この問題を回避するより良い方法は、:focus と :focus-visible ポリフィルを組み合わせることです。最初のコードブロックはポリフィルの仕組みを示しており、その下のサンプルアプリはポリフィルを使用してボタンのフォーカス インジケーターを変更する例を示しています。
/*
This hides the focus indicator if the element receives focus with a
mouse, but it still shows 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 {
...
}