:focus 伪类本身不提升可访问性,但正确使用能防止崩溃;它仅是样式钩子,关键在于提供清晰、高对比、不依赖颜色的焦点指示,且需规避 outline 被覆盖、缺失替代样式、未设 outline-offset、移动端蓝光消失等常见陷阱。

:focus 伪类本身不提升可访问性,但正确使用它能防止可访问性崩溃。 它只是个样式钩子;真正起作用的是你用它做了什么——尤其是是否提供了清晰、高对比度、不依赖颜色的焦点指示。
为什么 :focus 样式经常“看不见”
不是 :focus 失效,而是视觉反馈被覆盖或隐藏了:
- 重置 CSS(如 Normalize.css 或 Tailwind base)默认设
outline: none,你写的a:focus { outline: 2px solid blue; }被覆盖了 - 写了
*:focus { outline: none; }却没补任何替代样式——键盘用户立刻“失明” - 用了
border替代outline,但没加outline-offset,导致焦点框被内容遮挡或挤出布局 - 在 iOS Safari 上设了
outline,却没意识到它会覆盖系统默认的蓝色发光效果,而新样式对比度又不足(WCAG 要求至少 3:1)
:focus 和 :focus-visible 到底怎么配着用
别用 :focus-visible 替代 :focus,它们解决不同问题:
-
:focus总是生效:鼠标点、Tab 切、JS.focus()都触发 → 必须提供基础焦点样式(哪怕只是outline) -
:focus-visible是浏览器判断“用户像在键盘导航”时才触发 → 适合做“仅键盘可见”的美化,比如虚线框 + 动画 - 兼容性要兜底:
@supports selector(:focus-visible)包裹美化规则,否则旧版 Safari/IE 直接忽略 - 优先级注意:
button:focus-visible会覆盖button:focus(同权重下后声明者胜),所以基础样式必须写在前面
安全又有效的 focus 样式写法
绕过常见陷阱的最小可行方案:
- 用
outline,不用border:它不占布局空间,不会引发重排,且符合 WCAG 对“非侵入式聚焦指示”的要求 - 显式设置
outline-offset(如2px),避免被父容器overflow: hidden剪掉 - 颜色选高对比度值,比如
#0066cc或#2d5d9f,别只靠色相区分(红绿色盲用户看不到) - 移动端需额外处理:iOS Safari 默认给
<input>加蓝光,一旦设outline就消失,必须手动补足对比度和尺寸 - 禁用
!important:它会让屏幕阅读器用户的自定义样式或浏览器强制高对比模式失效
真正难的不是写对一行 input:focus,而是确保它在整个组件库、所有第三方 UI 框架、每种设备和辅助技术环境下都稳定可见。样式可能被覆盖十次,但只要有一次没 fallback,键盘用户就卡在页面中间找不到路。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











