Bootstrap 5 中无 focus-ring 类,实际使用 .focus-visible 配合 :focus-visible 实现键盘焦点环;自定义元素需设 tabindex="0" 并用 :focus-visible 或 .focus-visible 类触发样式。

Focus-ring 类在 Bootstrap 5 中默认不生效?
因为 focus-ring 不是 Bootstrap 5 原生类名——它根本不存在。Bootstrap 5 用的是 .focus-visible 配合 :focus-visible 伪类做“仅键盘触发的焦点样式”,而社区常说的 “focus ring” 实际指代这个行为。
常见错误现象:tab 切换时没高亮、鼠标点击后还留着蓝框、自定义样式完全不触发。
- Bootstrap 5 默认只对
button、a、input等原生可聚焦元素启用:focus-visible样式 - 如果你给
div加了tabindex="0",但没手动加.focus-visible支持,它不会自动获得焦点环 -
.focus类(旧版 Bootstrap 的)在 v5 中已废弃,硬写上去也没效果
怎么让自定义组件支持 focus-visible 行为?
核心是两件事:确保浏览器识别该元素为“键盘焦点目标”,并让 CSS 能捕获到 :focus-visible 状态。
使用场景:封装一个带 tabindex="0" 的卡片、下拉菜单触发器、或模拟按钮的 div。
- 必须显式设置
tabindex="0"(不能只靠 CSSoutline) - CSS 中不要只写
:focus,要写:focus-visible或&.focus-visible(后者需配合 JS 手动切换) - 推荐直接复用 Bootstrap 的
.focus-visible工具类(v5.3+ 内置),它内部就是基于:focus-visible的 polyfill 兜底逻辑 - 如果需要兼容老浏览器(如 Safari focus-visible polyfill 并初始化
简短示例:
<div class="card" tabindex="0">
<div class="card-body focus-visible">按 Tab 可聚焦我</div>
</div>
<style>
.card:focus-visible .card-body,
.card .card-body.focus-visible {
outline: 2px solid #0d6efd;
outline-offset: 2px;
}
</style>
为什么有时 focus-visible 样式不出现?
不是代码写错了,大概率是浏览器策略或交互方式触发了 :focus-visible 的抑制逻辑。
参数差异和兼容性影响:
- 鼠标点击后,Chrome / Firefox 默认不触发
:focus-visible(只触发:focus),这是规范行为,不是 bug - Safari 在某些版本中对非表单元素的
:focus-visible支持不稳定,建议加 polyfill - 如果页面有
outline: none全局重置,又没补:focus-visible,那焦点就彻底“消失”了 - 移动端 Safari 对触摸后的焦点行为更保守,可能全程不触发
:focus-visible
如何安全地覆盖 Bootstrap 的焦点样式?
别碰 $enable-focus-ring Sass 变量——它只控制内置组件是否生成 :focus-visible 规则,不影响你自己的样式。
实操建议:
- 优先用
:focus-visible替代:focus,避免鼠标点击也套上环 - 如果必须统一所有焦点行为(比如设计要求“无论怎么聚焦都要显示环”),就用
:focus+!important,但要清楚这会损害可访问性 - 修改
$focus-ring-width、$focus-ring-color等变量只影响 Bootstrap 内置组件(如btn),不影响你写的自定义规则 - 注意
outline-offset值:太小会被内容遮挡,太大显得悬浮,Bootstrap 默认是2px
:focus-visible 策略,什么时候又得绕过去——这得看具体交互逻辑和无障碍需求。


















