フォーカスリングの役割とマウスユーザーに向けた対応について

ブラウザは、フォーカスされた要素を可視化するためにフォーカスリングを実装している。青や黒のフォーカスされた要素を囲う枠線のことだ。outlineプロパティで表現される。これは主に、ウェブページをキーボードで操作可能にするためにある。

例として、ウェブページ上のボタンをクリックするという場面を想定する。キーボードによる操作では、まず、Tabキーなどによってフォーカスの位置を移動させながら、フォーカスを目的の要素まで辿り着かせる必要がある。その上で、スペースキーやエンターキーによってクリックに相当するアクションを実行する、というような流れになる。このような操作を行うためには、どの要素がフォーカスされているかを、ユーザーが視覚的に認識できることが前提になる。フォーカスリングが実装されているおかげで、開発者は適切なマークアップを行うだけでフォーカスを可視化することができる。

しかしながら、マウス操作を行うユーザーにとってはフォーカスの可視化は重要でないと言えそうだ。キーボードユーザーは、フォーカスを経てアクションを実行することが多い。だが、マウスユーザーは、要素をフォーカスさせるという行動を経由する必要が無いため、フォーカスを意識する必要性が低い。むしろ、フォーカスを意識していないため、フォーカスが可視化されているために操作上での混乱を呼ぶという可能性もある。

ブラウザはフォーカスリングを必要に応じて表示する。<button>要素の場合、マウスでのクリックによってフォーカスされた際にはフォーカスリングは表示されない。だが、キーボード操作によってフォーカスされた際にはフォーカスリングが表示される。これは前述したように、マウスユーザーにとってはフォーカスが可視化されている必要性が低いという考えに基づいている。とは言うものの、これは開発者によってスタイルが設定されてない場合の<button>要素の挙動であり、任意のスタイルを設定した途端、入力デバイスに関わらずフォーカスリングが表示されるようになってしまう。
一方、テキストフィールド(textタイプの<input>要素など)の場合、フォーカスリングは入力デバイスに関わらず表示される。これは、マウスによってフォーカスされようとも、キーボードによる入力が続く可能性が高いためだと考えられる。キーボード入力を行う以上、ユーザーはマウス操作時ほど明確に入力対象の要素を認識できない。そのため、キーボード入力が主になるUIの場合、フォーカスするために用いられた入力デバイスに関わらず、フォーカスリングは表示すべきだろう。また、項目数の多いフォームへ入力を行う際は、どのフィールドに対して入力途中であるかが明確になり、一時的にフォームから注意がそれてしまっても容易に入力を再開できるという利点もある。

以上の事情を考慮すると、ボタンはキーボード入力時のみ、テキストフィールドは常にフォーカスリングが表示されて欲しい。幸いにも現在のところ、このようにフォーカスリングを表示すべき場合にだけマッチする:focus-ring疑似クラスが提案されている:focus-visibleにリネームされた。これが実装されると、次のような宣言によって求めている挙動を実現できる。

:focus {
  outline: none;
}

:focus-ring {
  outline: 2px dotted dimgray;
}

マウス入力の際にどの要素がマッチしないかという判断に関しては、Firefox:-moz-focusring疑似クラスという独自実装や、focus-ringポリフィルを参考にできる。

残念ながら、:focus-ring疑似クラスはまだ実装されていない仕様であるため、代わりにJavaScriptを用いてそれに相当するような実装をすることになる。What Input?というライブラリを利用すれば、入力デバイスを検出してCSSから参照することができる。検出した入力デバイス<html>要素のdata-*属性に反映されるため、セレクタとして次のように利用するパターンが考えられる。

@mixin focus-with-keyboard {
  html[data-whatinput="keyboard"] &:focus {
    @content;
  }
}

@mixin focus-without-keyboard {
  html[data-whatinput="initial"] &:focus,
  html[data-whatinput="mouse"] &:focus,
  html[data-whatinput="touch"] &:focus {
    @content;
  }
}

@mixin focus-clear {
  outline: none;
}

@mixin focus-clear-without-keyboard {
  @include focus-without-keyboard {
    @include focus-clear;
  }
}
// キーボード操作時以外はフォーカスリングを非表示
.my-button {
  @include focus-clear-without-keyboard;
}
// デフォルトのフォーカスリングを非表示、キーボード操作時のみ独自のフォーカススタイルを適用
.my-button {
  @include focus-clear;

  @include focus-with-keyboard {
    background-color: lightgray;
    outline: 2px solid red;
  }
}
// デフォルトのフォーカスリングを非表示、常に独自のフォーカススタイルを適用
.my-text-field {
  @include focus-clear;

  &:focus {
    outline: 3px solid green;
  }
}

少なくないウェブサイトからフォーカスリングが取り除かれてしまっているのは、マウスユーザーに対する個別最適化の結果だろう。そもそも開発者でさえフォーカスを意識していないことすら考えられる。これらは、フォーカスの明示がマウスユーザーに混乱を与えているということの結果ではないか。とすると、フォーカスリングの見た目が悪いから代替のスタイルを設定する、というような話は論点がズレていて、フォーカスを意識する必要のないユーザーに対してもフォーカスを明示していたことが間違いだったと考えるべきではないか。

キーボードユーザーにのみフォーカスリングを表示するという実装方法が、これからのデファクトになっていくべきだと僕は思う。