スタイル フォーカス

フォーカス インジケーター(多くの場合、フォーカス リングで示されます)は、ページ上でフォーカスされている要素を特定します。マウスを使用できないユーザーや使用したくないユーザーにとって、このインジケーターはマウスカーソルの代わりとなるため、非常に重要です。

ブラウザのデフォルトのフォーカス インジケーターがデザインと競合する場合は、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、ALTOPTIONCONTROL キーが含まれていない場合、: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 {
  ...
}