:focus-within 要想生效,必须作用于具备“可聚焦上下文”的父容器,如加 tabindex="-1" 或使用 fieldset/form 等语义化元素;避免 display: contents、visibility: hidden 或无盒模型的空 div,且高亮宜用 outline 或 box-shadow 而非影响布局的属性。

:focus-within 要想高亮整个表单区域,必须写在能包裹可聚焦子元素的父容器上,且该容器得是“可聚焦上下文”——否则样式永远不会触发。
为什么 .form-group:focus-within 没反应?
根本不是伪类写错了,而是浏览器压根没把父容器当“监听者”:
-
.form-group是纯div,默认不可参与焦点流,:focus-within无从监听 - 子
input外层套了display: contents或visibility: hidden的 wrapper,焦点链被切断 -
label和input是分离结构(label[for="x"] + input#x),但外层没设tabindex="-1" - React/Vue 自定义组件里,原生
input被透传了tabindex="-1"或加了pointer-events: none
怎么写才真正触发 :focus-within
关键不是“加伪类”,而是让父容器具备“感知能力”:
- 给包裹容器加
tabindex="-1":不干扰 tab 顺序,只让它成为监听上下文 - 优先用语义化容器,比如
fieldset、form或 Bootstrap 的.form-floating(v5.3+ 已内置兼容逻辑) - 避免用
span或空div包裹input,确保父容器有盒模型(至少带padding或border) - 别给整个
form加:focus-within,否则点按钮也会高亮,误触率高
高亮样式一改 margin 或 height 就翻车
很多“失效”其实是视觉副作用导致的跳动或覆盖,不是伪类没生效:
立即学习“前端免费学习笔记(深入)”;
- 别在
:focus-within规则里改height、margin或display——表格中tr高度变化会跳动 - 优先用
outline: 2px solid #007bff:不占空间、无重排、符合可访问性要求 - 用
box-shadow: 0 0 0 2px rgba(0,123,255,0.25),别加inset,否则阴影往里缩盖住文字 - IE 完全不支持,旧版 Safari(15.4 之前)也不行;如果项目要跑内网或老系统,必须配 JS fallback 监听
focusin/focusout并切 class
最常被忽略的是:伪类生效 ≠ 样式可见。容器没盒模型、焦点链被 display: contents 断开、或高亮改了布局属性,都会让你以为它“不工作”。


















