:focus-within必须写在父容器上才生效,因其专为“监听者”设计;.form-group默认不可聚焦,需加tabindex="-1"或改用.form-floating等语义化容器,且子元素焦点链不能被display:contents等样式中断。

:focus-within 能让父容器响应内部任意可聚焦子元素的焦点状态,一行 CSS 就能高亮整块表单区域——不用 JS、不操心 label 点击、不处理 tab 切换竞态。
为什么 .form-group:focus-within 不生效
根本不是伪类写错了,而是父容器没成为“可聚焦上下文”或焦点链被意外切断:
-
.form-group是纯div,默认不可聚焦,:focus-within无从监听 -
input被套了display: contents的 wrapper,浏览器无法确认焦点落点 -
label和input是分离结构(label[for="x"] + input#x),但外层没设tabindex="-1" - 自定义组件里原生
input被加了tabindex="-1"或pointer-events: none
怎么写才真正触发 :focus-within
必须确保父容器能参与焦点流,且子元素真实可聚焦:
- 给
.form-group加tabindex="-1":不干扰 tab 顺序,但让它成为监听上下文 - 避免用
span或空div包裹input,优先选有盒模型的容器(如div、fieldset、.input-group) - Bootstrap v5.3+ 直接用
.form-floating,它已内置兼容逻辑 - 别给整个
form加:focus-within,否则点按钮也会高亮,误触率高
高亮样式容易翻车的三个地方
视觉反馈要明显,但不能破坏布局或键盘导航:
- 别在
: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 之前)也不行;如果项目要跑内网或老系统,不能只靠 :focus-within,得配 JS fallback 监听 focusin/focusout 并切 class。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











