結論

プロは focus リングを「飾り」ではなくアクセシビリティ契約として扱う。outline を消すなら必ず同等以上の代替を同じセレクタに置き、:focus-visible でキーボード時だけ表示し、WCAG の2つの 3:1 コントラスト(フォーカス前後の変化=SC 2.4.13/隣接色との差=SC 1.4.11)と「2 CSS px 厚の外周分」の最低面積を満たす。主役は overflow:hidden や forced-colors に強い outline、背景が読めない場面では黒+白の二色ハローを重ねるのが定石だ。

01 — outline を消すなら、必ず同じセレクタで置き換える

outline:noneoutline:0 を代替なしで書いた瞬間、キーボード利用者は「今どこにいるか」を完全に見失う。ブラウザ標準のフォーカスリングは WCAG のコントラスト要件が免除されているが、CSS で上書きした途端に 3:1 と最低面積の責任は自分に移る。これは WCAG SC 2.4.7(Level A)違反で、「焦点が消えてる」の最大の原因。ルールは単純で、outline:none と書いたら同じセレクタに必ず代替リングをセットで書く。

✗ outline:none だけ → 見た目はすっきりだがフォーカスが完全に消える
✓ 同じ要素に 2px solid のリングを置く → どこにいるか分かる

blogWebAIM: Contrast and Color Accessibility

02 — :focus ではなく :focus-visible でキーボード時だけ出す

:focus で常時リングを出すと、マウスクリックやタップのたびに太いリングが現れてビジュアルノイズになる。それを嫌ったデザイナーが結局 outline:none に走る——この悪循環が事故の温床だ。:focus-visible は UA のヒューリスティックでキーボード操作時のみリングを表示し、ポインタ操作では出さない。これでノイズを抑えつつキーボードアクセシビリティを維持でき、「消したくなる動機」そのものが消える。Baseline で2022年3月から主要ブラウザ対応済み。

✗ :focus → マウスクリックでも太いリングが残りノイズになる
✓ :focus-visible → マウス時は静か、Tab で来たときだけ出る

primary:focus-visible CSS pseudo-class — MDN Web Docs

03 — 3:1 を満たす太さと色で。薄い細リングは「無いのと同じ」

「主張させたくない」という心理から、つい 1px #ccc や半透明グレーの細リングにしてしまう。だが SC 1.4.11 は、フォーカス状態のリングが隣接色に対して 3:1 のコントラストを持つことを求める。薄く細いリングは明るい背景や写真の上で消え、実質「無いのと同じ」になる。色は明背景・暗背景・写真上など複数の隣接色でテストし、最低面積(後述の 2 CSS px 厚相当)も同時に確保する。

✗ 1px #ccc → 紙色の上で 3:1 を割り、ほぼ見えない
✓ 3px の十分なコントラスト色 → どの背景でも視認できる

primaryUnderstanding SC 2.4.13: Focus Appearance | WAI | W3C

04 — 主役は outline。box-shadow だけはクリップで消える

「角丸に追従するから」と box-shadow 単独でリングを作ると、overflow:hidden の親(カード・モーダル・スクロール領域)の内側でクリップされて消える。さらに Windows ハイコントラスト/forced-colors では box-shadow が剥がされ、リングが丸ごと消滅する——デバッグしにくい不可視バグだ。一次指標は outline 2–3px solid + outline-offset にする。outline はクリップされず forced-colors でも残り、現代ブラウザは outline でも border-radius を尊重するので、かつて box-shadow が好まれた理由は解消した。box-shadow はハローへ降格する。

box-shadow
✗ box-shadow だけ → overflow:hidden の親にリングがクリップされ消える
outline
✓ outline 主体 → クリップ親をはみ出して必ず見える

blogVisible Focus Rings: A Practical Guide for 2026 — 72Technologies

05 — 背景が読めないなら、黒+白の二色リングで両賭けする

単色リングは一部の隣接色で必ず 3:1 を割る。暗い写真の上に黒リングを置けば沈むし、白リングは明るい背景で消える。黒 outline と白 box-shadow ハローを重ねた「サンドイッチ/Oreo」型なら、明暗どちらの背景でも片方の色が必ずコントラストして見える。LP・バナー・テーマ切替・写真や動画の上など、背景色が固定でない再利用コンポーネントの安全策だ。

✗ 単色(黒)リング → 暗い背景の上で輪郭が沈んで読めない
✓ 黒+白の二色ハロー → 暗背景では白が、明背景では黒が効く

blogA guide to designing accessible, WCAG-conformant focus indicators — Sara Soueidan

06 — forced-colors とレガシーのフォールバックを置く

forced-colors(Windows ハイコントラスト)では box-shadow が剥がされるため、@media (forced-colors: active) でシステムカラーキーワード(CanvasText など)の outline に切り替える。:focus-visible 非対応の旧ブラウザには @supports not selector(:focus-visible):focus フォールバックを与える。行政・BtoB などアクセシビリティ要件が厳しい本番ではここまで用意する。下のデモは forced-colors 時に色がシステム由来に置き換わる挙動を、二色ハロー(不安定)と単色 outline(安定)で対比したもの。

✗ ハロー頼み → forced-colors で box-shadow が剥がれ白い縁が消える
✓ outline 主体 → forced-colors では CanvasText に切替えて必ず残る

blogVisible Focus Rings: A Practical Guide for 2026 — 72Technologies

実装スニペット

デフォルトの第一選択。多くの UI でこれが最適解。max(2px, 0.08em) にすれば要素サイズに追従する。

:focus-visible {
  outline: 2px solid var(--color-focus-ring, #1a73e8);
  outline-offset: 2px;
}

/* マウスクリックの :focus ノイズを消す(レガシー保険) */
:focus:not(:focus-visible) {
  outline: none;
}

背景が読めない LP・バナー向け。黒+白の二色リングと、主要 CTA 用の Oreo 二重リング。

:focus-visible {
  outline: 3px solid black;
  box-shadow: 0 0 0 6px white;
}

/* より高い視認性が要る主要 CTA 等(Oreo 二重リング) */
.cta:focus-visible {
  outline: 9px double black;
  box-shadow: 0 0 0 6px white;
}

outline を一次指標にしつつ、busy 背景でハロー(box-shadow)でプロミネンスを足す。ハローが消える環境でも 3:1 を維持できる。

.button:focus-visible {
  outline: 2px solid var(--color-focus-ring, #1a73e8);
  outline-offset: 2px;
  box-shadow: 0 0 0 4px var(--color-focus-ring-halo, rgba(255,255,255,.9));
}

forced-colors と :focus-visible 非対応のフォールバック。本番で最も堅い構成。

.button:focus-visible {
  outline: 3px solid deepskyblue;
  outline-offset: 3px;
}

@supports not selector(:focus-visible) {
  .button:focus {
    outline: 3px solid deepskyblue;
    outline-offset: 3px;
  }
}

@media (forced-colors: active) {
  .button:focus-visible {
    outline: 2px solid CanvasText;
  }
}

チェックリスト

  • outline:none / outline:0 を書いた箇所すべてに、同じセレクタの代替リングがセットで存在する
  • リングは :focus-visible で出している(:focus 常時表示でマウスノイズを出していない)
  • リング色は隣接色に対して 3:1(SC 1.4.11)。明背景・暗背景・写真上で実測した
  • フォーカス前後で同じピクセルが 3:1 変化する(SC 2.4.13 の change-of-contrast)
  • 面積は 2 CSS px 厚の外周分以上。dashed/dotted を使うなら約 4px に倍増させた
  • 一次指標は outlineoverflow:hidden の親内・スクロールコンテナ内でクリップされて消えないか確認した
  • 背景が固定でない再利用コンポーネントは黒+白の二色(Oreo)リングにした
  • @media (forced-colors: active)CanvasText 等のシステムカラー outline に切替えた
  • @supports not selector(:focus-visible) で旧ブラウザに :focus フォールバックを置いた
  • 色値(#1a73e8/deepskyblue 等)は例示。実際の隣接色で 3:1 を満たすか各自テストした

限界 / 出典

数値(3:1、2 CSS px 厚の外周分、Baseline 2022-03)は W3C/MDN/WebAIM の一次・準一次ソースで一致しており信頼度は高い。注意点は4つ。

適合レベルの表記揺れ:SC 2.4.13 Focus Appearance は Level AAA。一方で原資料間(Soueidan 記事内でも AAA とする箇所と「要件」として扱う箇所がある)に表記揺れがある。法的義務は WCAG 2.1 AA を基準とする案件が多く、2.4.13(2.2 追加)の扱いは契約要件で必ず確認すること。本記事では「実務上の良い設計目安」として AAA 基準を採用している。
box-shadow 二色リングの弱点:box-shadow ベースの黒+白リングは overflow:hidden の親内でクリップされ、forced-colors で剥がされる。クリップする親を持つコンポーネントでは outline 主体版に寄せること。
ブログ品質ソース:72Technologies と CSS-Tricks はブログ品質(個人/企業の実務知見)で規範ソースではない。具体的な色値(deepskyblue/#1a73e8 等)は例示であり、実際の隣接色に対して 3:1 を満たすかは各自テスト必須。
outline の border-radius 尊重:「最近のブラウザは outline で border-radius を尊重」は2026年時点の前提で、極端に古い環境では成り立たない可能性がある。重要案件では実機確認を。

blogA guide to designing accessible, WCAG-conformant focus indicators — Sara Soueidan

primaryUnderstanding SC 2.4.13: Focus Appearance | WAI | W3C

blogWebAIM: Contrast and Color Accessibility

primary:focus-visible CSS pseudo-class — MDN Web Docs

blogStandardizing Focus Styles with CSS Custom Properties — CSS-Tricks

blogVisible Focus Rings: A Practical Guide for 2026 — 72Technologies