【実務・中級編】 :focus 疑似クラス – CSS実践ガイド

やあ。今日も今日とてCSSと格闘ご苦労様。
君も中級の壁を突破し、デザインの再現性だけでなく「アクセシビリティ」や「インタラクションの質」にこだわり始めるフェーズに入った頃だと思う。

さて、今回はCSSの基礎の基礎でありながら、実務の現場では「なんとなく動くから」で済まされがちな `:focus` 疑似クラス について徹底的に深掘りしようか。

「フォーカスなんて、`outline` を消して終わりだろ?」なんて思っていたら大間違い。そこにはブラウザのアクセシビリティツリーとの対話があり、アクセシビリティ(a11y)の担保という、フロントエンドエンジニアとしてのモラルと技術力が問われる深い沼が広がっているんだ。

今日は、ブラウザの裏側の動きから、実務で即座に使える美しく堅牢な実装パターンまで、シニアの視点ですべて伝授する。心して読んでほしい。

—

1. `:focus` とは何か? ブラウザの裏側で何が起きているのか

まずはおさらいだ。`:focus` は、キーボードの Tab キーによる移動や、マウスでのクリック、プログラムからの `.focus()` 実行などによって、ユーザーからの入力を受け付ける状態(フォーカス状態)にある要素を捉える疑似クラスだ。

ここで一歩踏み込んで、ブラウザが裏側でどう処理しているかを考えてみよう。

OSやブラウザは、ユーザーが画面上のどこにいるのかを常に「フォーカスリング(多くは青い外枠)」という視覚的フィードバックで示している。これは単なる装飾ではなく、視覚障がいを持つユーザーや、マウスを使わずにキーボード操作のみでWebサイトを回遊するパワーユーザーにとっての「命綱」だ。

よくある悪手が、これだ。

/ 絶対にやってはいけないアンチパターン /

  • {

outline: none; / または outline: 0; /
}

これをやるとどうなるか? マウスユーザーにはスッキリした画面に見えるかもしれないが、キーボードで操作しているユーザーは「今、ページ上のどこにいるのか」が完全に迷子になる。アクセシビリティ監査ツール(Lighthouseなど)で一発レッドカードをくらうやつだな。

プロのフロントエンドエンジニアなら、「外枠を消す」のではなく、「デザイン性を損なわずに、より美しく文脈に合ったフォーカススタイルを再定義する」アプローチを取るべきだ。

—

2. 実務で直面する「マウスとキーボードのジレンマ」

`:focus` を扱う上で、誰もが一度は頭を悩ませる問題がある。
「クリックしたとき(マウス操作)にはフォーカスリングを出したくないが、キーボードで移動したときにはハッキリと出したい」という要望だ。

マウスでボタンをクリックした後に青い枠が残るのがカッコ悪いからといって、単に `outline: none` を指定すると、前述の通りキーボードユーザーが路頭に迷う。

このジレンマをスマートに解決するために生まれたのが、近代CSSの傑作 `:focus-visible` 疑似クラス だ。

`:focus` と `:focus-visible` の使い分け

  • `:focus`: 要素がフォーカスを得た瞬間に無条件で発火する。
  • `:focus-visible`: ブラウザのヒューリスティクス(ユーザーの操作デバイスや文脈)に基づき、「キーボード操作でフォーカスが必要だ」と判断された場合にのみ発火する。

実務では、基本のベーススタイルに `:focus-visible` を組み合わせて使うのが、現代のスタンダードなベストプラクティスだ。

—

3. コピペで使える! 実践的かつアクセシブルなデザインパターン

百聞は一見に如かず。実務でそのまま使える、アクセシビリティと美しさを両立させたCSSスニペットを共有しよう。

今回は、ボタンやリンク、カスタムフォームパーツに応用できる汎用的なアプローチだ。

/ ==========================================
1. グローバルな基本リセット:全要素のデフォルトoutlineを安全に上書き
================================———- /
:focus {
/ ブラウザ標準の不格好なフォーカスリングを一度リセット /
outline: none;
}

/ ==========================================
2. インタラクティブ要素のスタイリング基準
================================———- /
.button,
.link,
.input-text {
/ フォーカス時のアニメーションを滑らかにするためのトランジション /
transition: outline-offset 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease;
}

/ ——————————————
パターンA:マウスとキーボードを賢く区別するモダンな方法 (:focus-visible)
—————————————— /
.button:focus-visible,
.link:focus-visible {
/ キーボード操作時のみ、アクセシブルで美しいフォーカスリングを付与 /
outline: 2px solid var(–color-primary, #0066cc);
outline-offset: 3px; / 要素から少し離すことで視認性を爆発的に上げるプロの技 /
}

/ ——————————————
パターンB:背景色やシャドウで魅せるリッチなカード・コンポーネント
—————————————— /
.card-interactive {
border: 1px solid #e0e0e0;
background-color: #ffffff;
}

/ マウスでもキーボードでも、フォーカスされたらリッチに浮き上がらせる /
.card-interactive:focus {
border-color: #0066cc;
/ box-shadowを使ったモダンなフォーカス表現 /
box-shadow: 0 0 0 4px rgba(0, 102, 204, 0.15);
}

/ ——————————————
パターンC:フォーム入力要素 (input / textarea)
—————————————— /
.form-input {
border: 1px solid #ccc;
border-radius: 4px;
padding: 0.75rem 1rem;
font-size: 1rem;
}

/ 入力中のフォーカスは明確に色とシャドウでフィードバック /
.form-input:focus {
border-color: #0066cc;
box-shadow: 0 0 0 3px rgba(0, 102, 204, 0.2);
/ outlineは使わず、box-shadowでデザインの一貫性を保つ /
}

コードの解説ポイント

1. `outline-offset` の活用: フォーカスリングを要素の境界線から少し外側(`3px`程度)に離すことで、デザインの輪郭を潰さずに視認性を劇的に高めることができる。これはデザイナーにも非常にウケが良いテクニックだ。
2. `box-shadow` による拡張: フォームやカードUIでは、`outline` だけでなく `box-shadow` を巧みに利用することで、柔らかい光が発光しているようなリッチなフォーカス状態を演出できる。
3. 変数(カスタムプロパティ)の利用: `–color-primary` のように色を外出ししておけば、デザインシステムの変更にも一瞬で追従できる。

—

たかが `:focus`、されど `:focus`。
ここにどれだけ気を配れるかで、そのエンジニアが「ただ画面を組み立てる人」なのか、「真の意味でユーザー体験(UX)を設計できるプロ」なのかがハッキリと分かれる。

次の案件からは、`outline: none` を安易に書いて冷や汗をかくようなことはしないように。ブラウザの仕様を味方につけ、誰にとっても使いやすい、誇れるコードベースを築き上げていってほしい。

さて、今日のセッションはここまでだ。何か質問があれば、いつでもSlackで声をかけてくれ。手を動かして、体に覚え込ませよう!

コメント

タイトルとURLをコピーしました