こんにちは。現場の第一線でコードを書き続けていると、「動けばいいや」で作られたアクセシビリティの爆弾のようなUIに出くわして、頭を抱えることがよくありますよね。
特に、フォームの入力欄やボタンをクリックしたときに、周りに現れるあの「青い枠(アウトライン)」。デザイナーから「これ、クリックしたときにもダサいから消して!」と言われ、思考停止で `outline: none;` と書いてアクセシビリティ担当の同僚に怒られた経験、中級エンジニアのあなたなら一度や二度ではないはずです。
今回は、その永遠の課題に終止符を打つ救世主、`:focus-visible` 疑似クラスについて徹底的に解説します。ブラウザの裏側の挙動から実務でのスマートな使いこなし方まで、シニアの視点でみっちりとお伝えしましょう。
—
なぜ `outline: none;` は「悪」なのか?
まず大前提として、マウスやタッチパッドで操作しているユーザーにとって、クリックした要素にフォーカスリング(枠線)が出るのは、確かに「見た目が野暮ったい」と感じることがあります。だからといって、CSSで一律に `outline: none;` を指定してしまうと、何が起きるでしょうか?
キーボードの「Tabキー」を使ってサイト内を移動している、視覚障害を持つユーザーやパワーユーザーたちが、「今、自分がページのどこにいるのか」を見失うのです。これはアクセシビリティ(a11y)の観点から絶対にやってはいけない御法度です。キーボード操作者からフォーカスリングを奪うことは、視覚障害者に「目隠しをして階段を歩け」と言うようなものです。
そこで登場するのが、この `:focus-visible` です。
—
`:focus-visible` の標準仕様と、ブラウザの裏側の動き
`:focus-visible` は、一言で言えば「ブラウザが『今、ユーザーはキーボード操作などでフォーカスインジケーターを必要としているな』と判断した瞬間だけ発動する」という、空気を読める賢い疑似クラスです。
従来の `:focus` は、「マウスでクリックしようが、JavaScriptで強制的にフォーカスしようが、キーボードで移動しようが、フォーカスが当たっていれば問答無用でスタイルを適用する」という、いわば融通の利かない奴でした。
ブラウザは裏側で何を考えているのか?
各ブラウザ(Chromium、Firefox、Safari)のエンジンは、ユーザーの入力モーダル(ポインティングデバイスか、キーボードか)を常に監視しています。
1. マウスでクリックした場合:
ブラウザは「こいつは今マウスを使っているな」と判断し、要素にフォーカスは当たりますが、`:focus-visible` の条件は満たしません(フォーカスリングは消えたままにできる)。
2. キーボードの Tab キーで移動した場合:
ブラウザは「今、視覚的なインジケーターがないとユーザーが迷子になる!」と判断し、`:focus-visible` を即座に発動させ、アクセシビリティのための視覚的な枠線をドンと表示します。
この仕組みにより、「マウスユーザーにはスッキリした見た目を提供しつつ、キーボードユーザーには迷わない親切心を両立させる」という、フロントエンドエンジニアの長年の夢がネイティブで実現できるようになったのです。
—
現場で即コピペして使える!実践的コードスニペット
実際のプロジェクトでどう書くべきか、私のチームでも採用しているベストプラクティスを共有します。
まずは、グローバルなベーススタイルとして、ブラウザデフォルトの粗野なアウトラインを一度リセットし、モダンで美しいフォーカススタイルを定義するのが定石です。
/ ==========================================
1. すべてのフォーカスからデフォルトの線を消す(ただしアクセシビリティは殺さない)
========================================== /
:focus {
outline: none;
}
/ ==========================================
2. キーボードフォーカス時のみ、リッチなアクセシビリティリングを付与する
========================================== /
:focus-visible {
/ ブランドカラーに合わせた、太めで視認性の高いアウトライン /
outline: 3px solid #2563eb;
outline-offset: 2px; / 要素から少し離すことで、デザイン性を高めつつ見やすくする /
border-radius: 4px; / 角丸のデザインにも自然に追従させる /
}
実務でよくある「ボタンと入力欄」の具体例
例えば、カスタムボタンやテキスト入力フォームを実装する際のコンポーネント単位の書き方はこうなります。
/ テキスト入力欄のスタイル /
.text-input {
width: 100%;
padding: 0.75rem 1rem;
border: 1px: solid #d1d5db;
border-radius: 0.375rem;
background-color: #ffffff;
transition: border-color 0.2s ease;
}
/ マウスホバー時はボーダーの色を変えるだけにする(野暮ったい枠線を出さない) /
.text-input:hover {
border-color: #9ca3af;
}
/ 通常の :focus ではなく、キーボード操作時のみアクセシビリティ用の枠線を出す /
.text-input:focus-visible {
outline: none; / 万が一の二重線を防止 /
border-color: #2563eb;
box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.2); / 美しい外側への光彩(グロウ効果) /
}
/ プライマリボタンのスタイル /
.primary-btn {
display: inline-flex;
align-items: center;
justify-content: center;
padding: 0.75rem 1.5rem;
background-color: #2563eb;
color: #ffffff;
font-weight: 600;
border: none;
border-radius: 0.375rem;
cursor: pointer;
transition: background-color 0.2s ease;
}
.primary-btn:hover {
background-color: #1d4ed8;
}
/ クリックした瞬間(active)のスタイリング(押し込まれた感を演出) /
.primary-btn:active {
transform: translateY(1px);
}
/ キーボードでフォーカスされた時のみ、視認性の高い二重リングや光彩を付与 /
.primary-btn:focus-visible {
outline: 2px solid #ffffff; / ボタンの背景色とのコントラストを担保 /
outline-offset: 2px;
box-shadow: 0 0 0 4px #1d4ed8;
}
このコードのポイントは、マウスでクリックした際には `.primary-btn:hover` や `:active` のスタイルしか適用されず、余計なフォーカスリングが画面に残らない点です。しかし、一度Tabキーでこのボタンにフォーカスを当てれば、鮮やかなリングが即座に出現し、キーボードユーザーを迷子にさせません。
—
シニアからの実務アドバイス・注意点
`:focus-visible` は非常に強力ですが、現場で使う上でいくつか注意すべき罠があります。
1. フォールバック(レガシーブラウザ対策):
古いブラウザ(IE11などは論外として、少し前のバージョンなど)は `:focus-visible` を解釈できません。そのため、前述したように「一律で `outline: none` を当ててから `:focus-visible` で上書きする」というアプローチをとると、非対応ブラウザでキーボードフォーカスが完全に消滅します。
- 対策: `@supports` クエリを使うか、最悪の場合でも最低限の `:focus` スタイル(ブラウザデフォルトの点線など)が残るようなCSS設計(プログレッシブ・エンハンスメント)を心がけましょう。現代の開発であれば、実質的に主要モダンブラウザのシェアはほぼ100%カバーできているため、そこまで過敏になる必要はありませんが、頭の片隅に入れておいてください。
2. デザイナーとの共通認識:
「クリックしたときに青い枠が出るのが嫌だ」という要望を受けたときは、頭ごなしに拒絶するのではなく、「マウスのときは出さないようにしますが、キーボードアクセシビリティのために、Tabキーで移動したときにはデザインされた綺麗な枠が出るように実装しますね」と、この `:focus-visible` の仕様をプロとして提案してください。これだけで、デザイナーやディレクターからの信頼がグッと上がります。
—
さあ、明日からのコーディングでは、思考停止の `outline: none;` はもう卒業しましょう。`:focus-visible` をスマートに使いこなし、デザイン性とアクセシビリティが高次元で融合した、プロフェッショナルなWebサイトを構築していってください。応援しています!

コメント