:focus-within在移动端搜索框失效非写法问题,而是safari(15.4前)和部分android chrome对其支持不稳定,软键盘弹出致input短暂失焦、焦点链中断,且需满足tabindex="-1"、同容器包裹、子元素可聚焦三前提;动画须用max-width+opacity替代width,配合role="combobox"与js兜底。

为什么:focus-within在移动端搜索框上大概率失效
不是写法错,而是 Safari(尤其 iOS 15.4 之前)和部分 Android Chrome 对 :focus-within + 宽度动画的支持不稳定;软键盘弹出时 input 常短暂失焦再重获焦,导致伪类快速切换、动画中断或直接不触发。点击放大镜图标后调用 input.focus(),某些版本也不响应。
:focus-within生效的三个硬性前提
缺一不可,否则容器根本不会匹配状态:
-
.search-container必须是可参与焦点流的上下文:加tabindex="-1"(不干扰 tab 顺序,但让它能监听) -
<input>和下拉列表(如<ul class="suggestions"></ul>)必须包裹在同一个父容器内 - 子元素必须真实可聚焦:避免
display: contents包裹input,禁用pointer-events: none或tabindex="-1"在输入框上
纯 CSS 展开动画必须避开的坑
用 :focus-within 控制展开,但动画实现方式决定成败:
- 别用
width动画:布局重排易导致 Safari 丢焦点;改用max-width+overflow: hidden - 初始
max-width别设为0,设为40px(容纳图标+留白),展开用max-width: min(320px, 80vw) - 下拉列表不能用
display: none切换:会导致键盘方向键无法聚焦补全项;应组合使用opacity: 0、visibility: hidden、pointer-events: none - 过渡属性必须显式声明:
transition: max-width 0.3s ease-in-out, opacity 0.2s ease;避免transition: all覆盖导致意外属性动画
无障碍与兼容性兜底必须做
仅靠 :focus-within 不够,尤其面对老系统或辅助技术:
- 给容器加
role="combobox"、aria-expanded="false",JS 在focusin时同步设为"true",focusout延迟 150ms 后设回"false" - 补全列表的
id必须被aria-controls显式引用,例如aria-controls="search-suggestions" - IE 完全不支持
:focus-within,Safari 15.4 之前支持弱;需 JS fallback 监听focusin/focusout并切换is-expanded类 - Chrome 自动填充常干扰样式,
autocomplete="new-password"比off更可靠
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











