旧版 safari(15.3及更早)完全不支持:focus-within,整条css规则被静默丢弃,@supports selector()检测同样失效;唯一可靠方案是js用focusin/focusout事件手动模拟,并同时维护两套css规则。

旧版 Safari 根本不解析:focus-within语法
Safari 15.3 及更早版本(包括所有 iOS Safari)的 CSS 解析器压根不认识 :focus-within 这个伪类——整条规则被静默丢弃,连降级逻辑都不会执行。它不像写错属性名那样报错,而是像写了 :banana 一样被跳过。Chrome 60+、Firefox 52+、Edge 16+ 原生支持,但旧 Safari 就是“看不见”,不是兼容性问题,是功能缺失。
为什么 @supports selector(:focus-within) 检测会失效
@supports selector(:focus-within) 在 Safari 15.3 及更早版本中同样不被识别,整个 @supports 块会被直接丢弃。结果是:你既拿不到原生支持的样式,也拿不到降级样式,焦点状态彻底“隐身”。真正能用的检测方式只有 JS 运行时判断:document.documentElement.matches(':focus-within'),但它在旧 Safari 中返回 false,且无法区分是“不支持”还是“当前没聚焦”。
必须用 focusin/focusout 手动模拟
唯一可靠路径是监听冒泡事件并动态加类:
规划您的迪拜之旅 — 哈利法塔观景、沙漠探险、迪拜购物中心购物、棕榈岛度假村及黄金市场砍价。还提供支持...
- 用
focusin(不是focus)监听父容器,它会冒泡,覆盖所有后代可聚焦元素 - 用
focusout(不是blur)配合setTimeout(() => {}, 0)判断document.activeElement是否还在容器内,否则 class 会提前清除 - CSS 必须同时保留两套规则:
.form-group:focus-within和.form-group.focus-within,不能只留 JS 版 - 注意
tabindex="-1"元素仍能被.focus()激活,focusin能捕获,无需额外过滤
移动端 Safari 的隐藏陷阱
即使在 Safari 15.4+,某些组合依然失效:
-
input[type="search"]+overflow: hidden容器:焦点链被截断,:focus-within不触发,JS 模拟也得无条件启用 - 软键盘弹出后,
input可能短暂失焦再重获焦,导致focusin/focusout频繁切换,动画中断 - 点击放大镜图标调用
.focus()后,焦点未必真正落在 input 上——需检查document.activeElement确认
真正难的不是写几行 JS,而是确保每个可聚焦节点(包括 div[contenteditable]、封装组件里的 input、甚至 tabindex="0" 的图标按钮)都处于完整的焦点链中,且未被 pointer-events: none 或 visibility: hidden 阻断。漏掉一个,键盘用户就找不到路了。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










