スタイル フォーカス

フォーカス インジケーター(多くの場合「フォーカス リング」で表されます)は、ページで現在フォーカスされている要素を示します。このインジケーターはマウスポインタの代用となるため、マウスを使用できないユーザーにとって非常に重要です。

ブラウザのデフォルトのフォーカス インジケーターがデザインと競合する場合は、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 {
  …
}