:focus-within必须写在父容器上才生效,加在input自身永远不触发;它专为“监听者”设计,要求父容器具备可聚焦上下文(如tabindex="-1"),且内部子元素真正可聚焦,否则因焦点链断裂而失效。

:focus-within 必须写在父容器上才生效,加在 input 自身上永远不触发——这是绝大多数“没反应”的根本原因。
为什么 :focus-within 加在 input 上完全无效
它不是 :focus 的替代品,而是专为“监听者”设计的伪类:只有能包含可聚焦后代的父级(比如 div、label、fieldset)才该加它。input 是叶子节点,浏览器直接忽略 .input:focus-within 这种写法。
-
input:focus负责改输入框自身样式(边框、阴影等) -
.form-group:focus-within才能让整个包裹区域响应:只要内部input、textarea、button或带tabindex的元素获焦,就立刻激活 - 常见错误写法:
.input:focus-within { }—— 永远不匹配
父容器必须具备可聚焦上下文,否则伪类不计算
纯 div 默认不可聚焦,:focus-within 不会凭空生效。它不要求父容器被 tab 进去,但必须处于可聚焦上下文中。
- ✅ 推荐:
<div class="form-group" tabindex="-1"> —— 仅需一次,不干扰 tab 顺序 <li>❌ 错误:<code><div class="form-group"> —— 没有聚焦能力,伪类永不计算 <li>别给整个 <code>form加:focus-within,点任意按钮也会触发,容易误高亮 -
label和input必须构成祖先-后代关系(<label><input></label>或<label for="x"></label><input id="x">),否则点击label不会触发 - 绝对别在
:focus-within规则里改height、margin或display—— 表格中tr高度变化会整行跳动 - 优先用
outline: 2px solid #007bff:不占空间、无重排、键盘导航友好 - 要用阴影,选
box-shadow: 0 0 0 2px rgba(0,123,255,0.25),别加inset,否则往里缩盖住文字 - 统一所有相关元素的
box-sizing为border-box,避免border+padding导致宽度溢出 -
display: contents或visibility: hidden包裹子元素,会导致浏览器无法确认焦点归属 - 自定义组件(如
<myinput></myinput>)中,原生input被设了tabindex="-1"或pointer-events: none - 父容器是纯文本节点,或没盒模型(没
padding、border、display),样式改了也看不见 - 在 Shadow DOM 中使用时,
:focus-within必须写在 shadow host 上,且子元素焦点需能穿透出来
高亮样式怎么写才不翻车
视觉反馈要明显,但不能引发重排、跳动或覆盖内容。很多“失效”其实是样式副作用导致的。
哪些结构会让 :focus-within 失效
失效几乎都源于焦点链断裂或渲染上下文缺失,不是 CSS 写错了,而是 DOM 或样式阻断了浏览器对“焦点落点”的判断。
真正麻烦的从来不是写一行 :focus-within,而是确保焦点能落到预期的原生 input 上,并且中间没有被样式或 DOM 结构悄悄拦住。











