一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

HTML如何做focus visible_html focus-visible焦点样式【收藏】

时间:2026-06-27 09:46:57 编辑:袖梨 来源:一聚教程网

:focus-visible 应用于需区分键盘Tab与鼠标点击焦点的场景;核心判断标准是是否需为键盘用户保留必要视觉反馈,同时避免鼠标用户看到冗余轮廓线。

直接用 :focus-visible 是最干净的方案,但浏览器支持不统一、polyfill 行为有坑,不能无脑上。

什么时候该用 :focus-visible 而不是 :focus

核心判断标准:是否需要区分键盘 Tab 导航和鼠标点击触发的焦点。

  • 鼠标点按钮 → 不想看到轮廓线?用 :focus-visible
  • 表单里按 Tab 切换输入框 → 必须有清晰视觉反馈?:focus-visible 正是为此设计
  • 项目已强制要求 WCAG 2.4.7(焦点可见性)合规?:focus-visible 是当前事实标准
  • 旧版 Safari(5%?得搭配 focus-visible polyfill,但要注意它监听 keydown 的时机可能漏掉首次 Tab

:focus-visible 的 CSS 写法和常见错误

别直接覆盖所有 :focus,否则会破坏可访问性。正确写法是分层控制:

  • 先清除非键盘场景的默认焦点样式:.js-focus-visible:focus:not(.focus-visible) { outline: none; }
  • 再定义键盘聚焦样式::focus-visible, .focus-visible { outline: 2px solid #2196F3; outline-offset: 2px; }
  • 如果用了 polyfill,HTML 必须有 class="js-focus-visible",否则第一行规则不生效
  • 别写 input:focus { outline: none; } 单独一行——这会让键盘用户彻底失去焦点提示
/* ✅ 推荐基础组合 */.js-focus-visible:focus:not(.focus-visible) {  outline: none;}:focus-visible,.focus-visible {  outline: 2px solid #2196F3;  outline-offset: 2px;}

移动端和 Safari 的兼容细节

Safari 15.4+ 原生支持 :focus-visible,但 iOS 上仍有两个现实问题:

立即学习“前端免费学习笔记(深入)”;

  • 软键盘弹出后,input 获得焦点时可能不触发 :focus-visible(尤其在 textarea 或带 autofocus 的场景)
  • 部分老版本 Safari(如 15.3)会把鼠标悬停也误判为键盘事件,导致鼠标用户看到轮廓线
  • 回退方案别只靠 @supports 检测,加一层 input:focus { outline: 2px solid #2196F3; }@supports not (:focus-visible) 块里更稳妥
  • 避免在 select 上只依赖 :focus-visible;iOS Safari 对下拉框的焦点事件捕获不稳定,建议同时设 select:focus { box-shadow: 0 0 0 2px rgba(33,150,243,0.3); }

polyfill 引入后的关键验证点

用了 focus-visible npm 包或 CDN 后,必须手动检查三件事:

  • 页面 <html> 标签是否自动加上了 class="js-focus-visible"?没加 = polyfill 没启动
  • 按 Tab 键时,元素是否动态获得 class="focus-visible"?没加 = 事件监听失败(常见于脚本加载过晚或被 defer 阻塞)
  • 鼠标点击后,焦点元素是否**没有** focus-visible 类?如果有,说明 polyfill 的 hadKeyboardEvent 状态未重置,可能是页面有其他脚本干扰了 mousedown 事件流

最易被忽略的是 polyfill 的初始化时机——它必须在 DOM ready 后立即执行,且不能被模块打包器误删(比如 Webpack 的 tree-shaking 把 import 'focus-visible' 当作无副作用代码干掉了)。

热门栏目