必须同时清除outline和box-shadow并覆盖所有焦点伪类组合,否则蓝边无法彻底去除;需用:focus-visible保留键盘用户焦点指示,firefox还需单独重置::-moz-focus-inner,ios则需设置-webkit-tap-highlight-color。

button:focus 为什么清不掉蓝边
只写 button:focus { outline: none } 大概率失效,因为现代浏览器(Chrome、Edge、Firefox)的焦点轮廓是 outline + box-shadow 双重叠加,尤其 Bootstrap 等框架还会主动加 box-shadow: 0 0 0 0.25rem rgba(13,110,253,.25)。单清 outline,阴影还在;单清 box-shadow,旧版 Firefox 仍会渲染默认虚线框。
:focus-visible 是什么,为什么它更安全
:focus-visible 是一个选择器,只在用户**用键盘操作(Tab/Shift+Tab)触发焦点时才匹配**,鼠标点击或触摸后不会激活它。这意味着你可以放心对它设 outline: none,而不会破坏键盘用户的可访问性路径。
常见误用:button:focus { outline: none } 一刀切,所有焦点都消失;正确做法是:
button:focus:not(:focus-visible) {
outline: none;
box-shadow: none;
}
这样保留了键盘焦点的视觉反馈,又去掉了鼠标点击后的“多余蓝边”。
- 注意 Safari 15.4+ 才完全支持
:focus-visible,低于此版本需降级 fallback - 不要依赖
*:focus { outline: none }—— 这会直接让所有表单控件失去焦点指示 -
:focus-visible不是伪类组合,不能写成button:focus-visible(缺少冒号),必须是button:focus-visible或button:focus:not(:focus-visible)
Firefox 的 -moz-focus-inner 必须单独处理
Firefox 对 <button></button> 和 <input type="button/submit/reset"> 内置了一个不可见的内边框(::-moz-focus-inner),它独立于 outline,会导致点击后出现细虚线或偏移感。这个属性无法被 :focus 或 :focus-visible 覆盖,必须显式重置:
button::-moz-focus-inner,
input[type="button"]::-moz-focus-inner,
input[type="submit"]::-moz-focus-inner,
input[type="reset"]::-moz-focus-inner {
border: none;
padding: 0;
}
漏掉这一条,Firefox 下按钮点击后仍可能“微微发虚”或尺寸跳动。
iOS 点击高亮不是 :focus 问题,别混在一起
iOS Safari / WebView 中点击按钮出现的半透明蓝色 overlay,和 :focus 完全无关,它是 WebKit 的系统级 tap 高亮行为。写再多 outline 或 box-shadow 都没用。
唯一有效解法是给具体可点击元素加:
.btn, .js-clickable {
-webkit-tap-highlight-color: transparent;
}
关键点:
- 不能写
* { -webkit-tap-highlight-color: transparent }—— 某些微信 WebView 会白屏 - Vue/React 动态渲染的按钮,需确保 class 名也命中该规则(比如用
class="btn"而非仅靠 scoped style) - 桌面 Chrome 的设备模拟器不触发该高亮,必须真机验证
真正难的不是“怎么去掉”,而是去掉之后——你是否已为键盘用户提供了等效的焦点提示(比如 border 变色、背景微调、或 focus-visible 专用样式)。否则,可访问性就断了。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











