【:focus-visible】フォーカス表示をタップ時は表示しないようにする

## これは何

`outline: none`や`outline: 0`が当たっている要素に`:focus`でoutlineなどのフォーカス表示指定すると、Tabキーでフォーカスした時だけでなく要素をクリックした時にもフォーカス表示が表示されてしまう現象の解決方法です。

## 結論

`:focus`ではなく`:focus-visible`を使ってフォーカス表示を指定する。

https://developer.mozilla.org/ja/docs/Web/CSS/:focus-visible

## 本文

`button`や`a`のようなフォーカスできる要素は、デフォルトで`Tab`でフォーカスした際に`outline`が表示されるようになっています。

この`outline`見た目のために`0`や`none`を指定して表示されなくすると、キーボード操作でWebを利用するユーザーが「今自分がどこの要素にフォーカスしているか」が視覚的に判断できなくなり、アクセシビリティが低下してしまいます。

🔽 リンクとボタンに`outline: none`が指定されているため、`Tab`でフォーカスしても視覚的にわからない

<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="BarvrJJ" data-user="kabechiyo" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/kabechiyo/pen/BarvrJJ">
  outline:none</a> by kabechiyo_shunkaaizawa (<a href="https://codepen.io/kabechiyo">@kabechiyo</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

そのため、`outline`の値を`0`や`none`にすることはしないか、する場合は大体のフォーカス表示が必要になります。

普段コーディングをしている際はブラウザがデフォルトで表示されるようになっているので問題ないのですが、たまに`reset.css`のような親要素や使用したライブラリに意図せず`outline: 0`や`outline: none`が当たっていることがあります。

こうした時、フォーカス表示を表示させたい要素に`:focus`を使って`outline`の指定をオーバーライドしてフォーカス表示を実装していました。
しかし、この`:focus`を使用することには一つ落とし穴があります。
それは、フォーカス表示が`Tab`キーでフォーカスした時だけでなく要素をクリックやタップした時にも表示されてしまうことです。
（safariの場合は表示されません）

🔽無事フォーカス時に表示が出るようになったが、クリック時にもフォカース表示が出てしまう...

<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="qBoLoyb" data-user="kabechiyo" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/kabechiyo/pen/qBoLoyb">
  Untitled</a> by kabechiyo_shunkaaizawa (<a href="https://codepen.io/kabechiyo">@kabechiyo</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

ボタンをクリックした時にまでoutlineが表示されるのは好ましくありません。

そんな時に、`:focus-visible`を使うと、Tabでフォーカスした時のみフォーカス表示を出すことができます！

> :focus-visible 擬似クラスは、要素が :focus 擬似クラスに一致している時で、ユーザーエージェントが要素にフォーカスを明示するべきであると推測的に判断した場合に適用されます (多くのブラウザーではこの場合、既定で「フォーカスリング」を表示します)。
> 
> このセレクターは、ユーザーの入力方法 (マウスなのかキーボードなのか) によって異なるフォーカス表示を提供したい場合に便利です。

🔽無事フォーカス時に表示が出るし、クリック時には表示が出ないようになりました！ :tada:

<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="rNdodZX" data-user="kabechiyo" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/kabechiyo/pen/rNdodZX">
  :focus-visible</a> by kabechiyo_shunkaaizawa (<a href="https://codepen.io/kabechiyo">@kabechiyo</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

こちらの方法は、[キーボードのタブ移動時はoutlineを表示し、マウスクリック時は非表示にする | NullNull](https://nullnull.dev/blog/css-focus-visible/)という記事で発見することができました :pray: _感謝_

2022年8月現在、Can I use...で確認するとChrome, Edge, Safari, Firefox, Operaなどの最新版でサポートされているようです！

https://caniuse.com/?search=%3Afocus-visible

## Ref

- [キーボードのタブ移動時はoutlineを表示し、マウスクリック時は非表示にする | NullNull](https://nullnull.dev/blog/css-focus-visible/)
- [:focus - CSS: カスケーディングスタイルシート | MDN](https://developer.mozilla.org/ja/docs/Web/CSS/:focus)
- [:focus-visible - CSS: カスケーディングスタイルシート | MDN](https://developer.mozilla.org/ja/docs/Web/CSS/:focus-visible)

## 最後に

よければこんなCSSやアクセシビリティ、あとは普段よく記事を書いているFigmaなどについてDevトークで情報交換してくださる方を募集中です...！ お気軽にご応募ください! :)

https://jobs.qiita.com/employers/qiita-inc/dev_talks/395