:focus-visible 比 :focus 更靠谱,因其仅在键盘导航(如tab、enter)时触发轮廓,避免鼠标/触摸/js聚焦时的误显示;需禁用全局outline: none并显式设置outline等样式才能生效。

focus-visible 为什么比 :focus 更靠谱
因为 :focus 一触发就画轮廓,鼠标点按钮、触摸屏点链接、甚至 JS 调用 element.focus() 都会激活它——但用户根本没按键盘,这时候画个蓝框反而干扰视觉。而 :focus-visible 是浏览器自己判断“这次聚焦是不是键盘驱动的”,只在 Tab、Shift+Tab、Enter、Space 等真实键盘导航场景下生效。
怎么让 focus-visible 真正生效
直接写 :focus-visible 不一定起作用,得配合两个关键点:
- 确保页面没禁用
outline: none的粗暴写法(尤其别在* { outline: none }这种全局规则里) - 必须显式设置
outline或其他可感知样式,比如:button:focus-visible { outline: 2px solid #007aff; outline-offset: 2px; } - 旧版 Safari(
focus-visible 和 autofocus、programmatic focus 的关系
页面加载时带 autofocus 的元素,或代码里调用 input.focus(),默认不会触发 :focus-visible——浏览器认为这不是用户主动键盘导航的结果。如果真想让这类聚焦也显示轮廓(比如表单自动聚焦后需引导键盘操作),得手动加 focus-visible 类或用 element.focus({ preventScroll: false, focusVisible: true })(Chrome 111+ 支持)。
容易被忽略的兼容性细节
:focus-visible 在 Firefox 中默认启用,在 Chrome/Edge 从 86 开始默认启用,但 Safari 直到 15.4 才支持,且早期版本行为不一致。更麻烦的是:某些 CSS 重置库(如 normalize.css 8.x 之前)或 UI 框架(如旧版 Bootstrap)会悄悄覆盖 :focus-visible 的默认行为,建议检查最终生成的 CSS 是否真的把 outline 应用到了该伪类上。调试时可以在 DevTools 里手动勾选 :focus-visible 状态看效果,比反复切键盘更可靠。
立即学习“前端免费学习笔记(深入)”;










