:focus-visible 能精准区分键盘与鼠标聚焦,但需正确声明顺序、避免全局 outline: none、确保元素可聚焦且焦点来源为键盘;否则不触发。
直接结论:用替代做焦点样式,就能让键盘用户看到清晰轮廓,鼠标用户完全不受干扰——但必须配合正确的声明顺序和 outline 恢复逻辑,否则它根本不会显示。
为什么
写了却没反应
最常见原因不是语法错,而是浏览器压根没“认为这次聚焦该被看见”:
鼠标点击后按空格/回车,
不触发(焦点来源仍是鼠标)
的元素首次被 Tab 进入时,部分浏览器(尤其 Safari)不激活它
页面加载后 JS 调用
,默认不算键盘导航,
不匹配
全局写了
,把
的基础样式也干掉了
调试时直接在控制台跑
,确认焦点是否真落在目标上,再检查它的
是否 ≥ 0 且未被
。
和
的声明顺序不能乱
必须先重置所有
的 outline,再用
单独恢复——靠层叠顺序自然降级,而不是靠
强顶:
立即学习
“
前端免费学习笔记(深入)
”;
这样写的效果是:
使用HTML,CSS,JavaScript开发Android应用程序 英文文字pdf版附源文件
如果你了解HTML,CSS和JavaScript,您已经拥有所需的工具开发Android应用程序。本动手本书展示了如何使用这些开源web标准设计和建造,可适应任何Android设备的应用程序 - 无需使用Java。您将学习如何创建一个在您选择的平台的Android友好的网络应用程序,然后转换与自由PhoneGap框架到一个原生的Android应用程序。了解为什么设备无关的移动应用是未来的潮流,并开始构建应用程序,提供更
下载
旧浏览器(如 Safari 15.3 及更早)只认第一行,所有焦点框消失
新浏览器执行两行:鼠标点按钮 →
生效但
不匹配 → 无 outline;键盘 Tab 进入 →
匹配 → 显示轮廓
如果写成
并列,旧浏览器会直接忽略整条规则(CSS 解析失败)
哪些元素默认不触发
不是加了
就一定能用,浏览器有内置判断逻辑:
✅ 默认触发:
、
、
、
、带
的
:focus-visible:focus:focus-visible:focus-visibletabindex="-1"element.focus():focus-visible* { outline: none }:focus-visibledocument.activeElementtabIndexdisabled:focus:focus-visible:focus:focus-visible!importantbutton:focus { outline: none; }
button:focus-visible { outline: 2px solid #007aff; outline-offset: 2px; }:focus:focus-visible:focus-visiblebutton:focus-visible, button:focus:focus-visibletabindex="0"tabindex="0"
❌ 默认不触发:
(无
href
)、
(即使有
tabindex="0"
)、
(除非显式设
tabindex
)
⚠️ 自定义组件(比如用
实现的开关)需确保有
role
+ 键盘事件监听,否则部分浏览器拒绝激活
:focus-visible
如果不确定,DevTools 里手动勾选元素的
:focus-visible
状态,比反复切键盘更快验证样式是否生效。
兼容性和可访问性细节不能漏
:focus-visible
在 Chrome 86+、Firefox 89+、Safari 15.4+ 原生支持;IE 完全不识别,旧版 Safari 行为不稳定。更关键的是:
别依赖
@supports (focus-visible: auto)
做兜底——它在 Safari 15.4 之前返回 false,但实际部分行为已可用
outline
颜色必须满足 WCAG 对比度要求(≥ 3:1),深色背景建议用
#007aff
,浅色背景可用
#5b3bff
第三方 UI 库(如旧版 Bootstrap 或某些 CSS-in-JS 方案)可能悄悄覆盖了
:focus-visible
的样式,务必在 DevTools 的 Computed 面板里查最终生效的
outline
真正容易被忽略的点是:autofocus 元素或 JS
.focus()
默认不触发
:focus-visible
,如果业务强依赖这个场景(比如表单自动聚焦后需引导键盘操作),得用
element.focus({ focusVisible: true })
(Chrome 111+ 支持)或手动加类兜底。
