只设 outline: none 无效,因 Bootstrap 蓝色边框由 outline 和 box-shadow 双重叠加构成;必须同时清除两者,并覆盖 .btn:focus、.btn:active:focus、.btn.active:focus、.btn.focus、.btn:active.focus、.btn.active.focus 所有状态。

只设 outline: none 不行,必须同时清除 outline 和 box-shadow,否则蓝边照常出现。
为什么 outline: none 单独写没用
Bootstrap 的“蓝色边框”不是纯 outline,而是 outline + box-shadow 双重叠加的效果。Chrome/Firefox 默认 focus outline 是系统色(深蓝或紫),而 Bootstrap 在 .btn:focus 里额外加了 box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25) —— 这才是你看到的那圈发亮蓝边。只清 outline,阴影还在;只清 box-shadow,旧版 Firefox 仍 fallback 显示 outline。
-
.btn:focus:键盘 Tab 进入或鼠标点击后获得焦点 -
.btn:active:focus:鼠标按下瞬间仍处于焦点态(松手前) -
.btn.active:focus:下拉 toggle 按钮等带 active 状态的按钮 -
.btn.focus和.btn:active.focus:Bootstrap 4/5 中 JS 动态添加的 class,也得覆盖
全局清除按钮蓝边的稳妥写法
把这段 CSS 放在你自己的样式文件末尾(确保加载顺序在 Bootstrap 之后),不用 !important 也能生效:
.btn:focus,
.btn:active:focus,
.btn.active:focus,
.btn.focus,
.btn:active.focus,
.btn.active.focus {
outline: none;
box-shadow: none;
}
- 别漏掉
.btn:active:focus:这是点击松手后蓝边“闪一下”的元凶 - 不推荐用
*:focus { outline: none }:会破坏所有可聚焦元素的可访问性 - 如果项目用了 Sass,确认没开启
$enable-focus-ring: true之类增强配置
输入框、下拉框、自定义 checkbox 同样要处理
别只盯着 .btn。所有可聚焦元素都走同一套机制:
立即学习“前端免费学习笔记(深入)”;
-
.form-control:focus:input / textarea 聚焦时的蓝边 -
.custom-select:focus:Bootstrap 自定义下拉框 -
.custom-checkbox input:focus + .custom-control-label:label 包裹的 checkbox/radio
对应清理示例:
.form-control:focus,
.custom-select:focus,
.custom-checkbox input:focus + .custom-control-label,
.custom-radio input:focus + .custom-control-label {
outline: none;
box-shadow: none;
border-color: #ced4da;
}
注意:border-color 必须显式设回非焦点色,否则某些主题下聚焦时边框仍会变蓝。
去掉蓝边后,键盘用户就“看不见焦点”了
这是最常被忽略的一点:移除 outline 和 box-shadow 后,仅靠键盘操作的用户无法判断当前焦点在哪。WCAG 要求提供等效视觉反馈。
- 推荐方案:
.btn:focus:not(:focus-visible) { outline: none; },只对鼠标点击隐藏轮廓,保留键盘 tab 的焦点指示 - 替代方案:用
background-color或border微调变化,但别让尺寸抖动(border会触发重排) - 若用
blur()主动失焦,务必放在异步回调里(比如 API 返回后),否则动画未结束就丢失焦点,体验断裂
真正卡住项目的,往往不是怎么写 CSS,而是没想清楚“用户怎么知道现在按的是哪个按钮”。


















