img:focus 无反应是因为 默认不可聚焦,需加 tabindex="0" 或 "-1" 才能触发;:focus-visible 仅键盘激活,推荐与 :focus 组合使用以兼顾无障碍;禁用 outline 必须提供等效视觉反馈。

不能只靠 :focus,必须配合 tabindex、:focus-visible 和键盘/鼠标行为检测逻辑,否则键盘用户会“看不见焦点在哪”。
为什么直接写 img:focus 没反应?
因为 <img> 默认不可聚焦——它既不是表单控件,也没声明交互能力。浏览器压根不把它放进 Tab 导航流,:focus 自然不会触发。
- 常见错误现象:点击图片或按 Tab 键,边框/轮廓完全不出现
- 解决路径只有两条:
tabindex="0"(加入导航流)或tabindex="-1"(仅支持 JS 聚焦) - 加了
tabindex="0"后,img:focus才真正生效,但要注意:这会让图片出现在 Tab 顺序里,可能干扰原有导航逻辑
:focus 和 :focus-visible 到底该用哪个?
:focus 一触发就上样式,鼠标点一下按钮也会亮;:focus-visible 只在键盘操作时激活,更精准。但两者不是互斥替代关系,而是分层控制。
- 推荐组合写法:
button:focus { outline: none; }+button:focus-visible { outline: 2px solid #0066cc; outline-offset: 2px; } - 这样既清掉鼠标点击的干扰样式,又保留键盘用户的视觉路标
- 注意兼容性:
:focus-visible在 Safari 15.4+、Chrome 86+、Firefox 86+ 支持;旧版浏览器会退回到:focus分支,所以必须确保:focus分支有可用样式(哪怕只是基础 outline)
如何让键盘用户聚焦时才显示焦点样式?
纯 CSS 无法监听“是键盘还是鼠标触发的聚焦”,但可以用 JavaScript 做轻量级行为标记,再配合 class 控制。
- 在
上监听:document.addEventListener('keydown', () => document.body.classList.add('keyboard-focus')) - 同时监听
mousedown或click移除 class:document.addEventListener('mousedown', () => document.body.classList.remove('keyboard-focus')) - 对应 CSS:
.keyboard-focus button:focus, .keyboard-focus [tabindex]:focus { outline: 2px solid #0066cc; } - 这个方案比
:focus-visible兼容性更好,且能覆盖所有可聚焦元素(包括div[tabindex]、img[tabindex]等)
移除默认 outline 是最危险的操作
很多框架(如 Bootstrap)默认加了 *:focus { outline: none !important; },这是无障碍红线。一旦删掉 outline,键盘用户彻底失去焦点位置感知。
- 绝对不要全局写
outline: none,除非你已提供同等或更强的视觉反馈(比如高对比边框 + 阴影 + 背景色变化) - 如果设计稿禁止“蓝圈”,请用
outline: 2px solid #0066cc; outline-offset: 2px;替代,而不是删 - 移动端 iOS Safari 有个特殊行为:点击后焦点可能残留,需额外用
element.blur()或监听touchend清理,否则焦点样式卡住不动
真正难的不是写对一行 :focus,而是判断哪些元素该进 Tab 流、哪些不该,以及在不同输入方式下保持反馈一致——这些没法靠 CSS 自动推断,得靠人工梳理交互路径。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











