:focus伪类未生效主因是元素不可聚焦、样式被覆盖或焦点事件被阻断;需检查tabindex、pointer-events、disabled等属性,确认outline是否被重置且有高对比度替代样式。

焦点没丢,是样式被覆盖或元素根本没聚焦——先查可聚焦性,再看层叠顺序。
为什么:focus写了却像没生效?
不是伪类失效,而是常见三类底层问题在干扰:
- 元素不可聚焦:比如
<div> 没加 <code>tabindex="0",或被pointer-events: none、disabled、readonly阻断 - 样式被覆盖:Normalize.css、Tailwind 或自定义重置规则里有
*:focus { outline: none; },且你没提供替代样式 - 开发者工具里
:focus伪类状态没变蓝:说明事件根本没触发,得检查 JS 是否调用了blur()或阻止了focus事件 - 显式清除默认轮廓:
outline: none(不是0),避免 Safari/Firefox 混合渲染 - 立刻补上可访问的替代样式:用
box-shadow比改border更稳,不会引起布局跳动;例如box-shadow: 0 0 0 2px rgba(79, 70, 229, 0.25) - 固定视觉尺寸:如果用
border,默认态和聚焦态必须保持border-width和border-style一致,否则会抖 - 深色背景慎用低 alpha:
rgba(13, 110, 253, 0.25)在黑底上接近透明,WCAG 要求对比度 ≥ 3:1,建议提 alpha 到 0.3 或换主色 - 首次页面交互是鼠标点击 → 后续整个会话中,浏览器可能暂时关闭:focus-visible判断逻辑
- JS 调用
element.focus()时没传{ focusVisible: true }(仅 Chromium 支持,且需配合HTMLElement.focusOptions) - 用了
autofocus属性:加载即聚焦,但浏览器不认为这是“键盘驱动”,:focus-visible不触发 - 自定义组件漏条件:比如
<div tabindex="0"> 必须加 <code>role="button"+keydown监听,js-focus-visiblePolyfill 才认它移动端 iOS Safari 的:focus陷阱
它对:focus的支持最苛刻,不是写错,而是平台限制:
- 非原生可聚焦元素(如
<div>、<code><span></span>)即使设了tabindex,也可能无法获得焦点 - 软键盘弹出后,某些场景下:focus样式会被系统强制覆盖或禁用
- 没有可靠的纯 CSS fallback:必须用 JS 监听
focusin事件 + 动态加类,才能确保视觉反馈不丢失 - 别信“iOS 15+ 就行”——iOS 15.4 才稳定支持
contenteditable的 :focus,旧版仍需降级
最常被忽略的点:移除
outline不等于完成任务,而是可访问性风险的开始。焦点样式是否真正可见,取决于它能否在任意设备、任意初始交互方式、任意辅助技术组合下稳定出现——这需要测试,而不是假设。 - 非原生可聚焦元素(如
如何让:focus样式稳定可见?
关键不是“显示”,而是“不被干掉”:
为什么:focus-visible有时死活不匹配?
它不是:focus的开关,而是浏览器内部启发式判断的结果,依赖真实交互上下文:
立即学习“前端免费学习笔记(深入)”;


















