spinner-border 默认动画通过@keyframes+border+currentColor实现:实色边框构成环形,border-right-color:transparent与border-radius:50%配合rotate(360deg)匀速旋转,缺一不可。

spinner-border 默认动画是怎么工作的
它靠的是 @keyframes spinner-border + border + currentColor 三者配合:用实色边框构成环形,右侧边框设为透明,再通过 transform: rotate(360deg) 让整个环匀速转一圈。关键点是 border-radius: 50% 和 border-right-color: transparent 缺一不可,否则不是圆环,而是四边形旋转。
常见错误现象:spinner-border 显示为方块、只转半圈、边缘锯齿明显、旋转中心偏移——基本都是因为覆盖了 border 样式但没同步重置 border-radius 或漏写了 transparent。
- 不要改
border-style:必须是solid,换成dashed或dotted会断开环形轨迹 - 别手动设
border-color:它依赖currentColor继承父级文字颜色,直接写死颜色会破坏text-primary等语义类效果 - 动画时长由
animation-duration控制,默认0.75s,调太快易眩晕,太慢(>1.2s)会让用户怀疑卡死
如何不写 JS 就让 spinner-border 随按钮尺寸自适应
Bootstrap 5 的 spinner-border 默认宽高是 2rem,而 .btn 的高度由 padding 和 font-size 动态决定,硬写 width: 2rem 必然错位。真正能联动的单位只有 em。
操作要点:
立即学习“前端免费学习笔记(深入)”;
- 给按钮加
position: relative; overflow: hidden -
spinner-border元素设为position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%) - 宽高统一用
em:对应.btn-sm用1.2em,.btn-md(默认)用1.5em,.btn-lg用1.8em - 确保按钮有明确
font-size(Bootstrap 默认是0.875rem或1rem),否则em会继承错误基准
绝对禁止用 scale() 缩放:会导致边框像素模糊、旋转中心偏移、高 DPI 屏幕下锯齿加重。
为什么加了 spinner-border 按钮文字却上跳或塌陷
根本原因是 spinner-border 是 display: inline-block,它和按钮内文字共处于同一行流,会参与行高计算。一旦插入,就会顶开原有文字位置,尤其在小屏幕或紧凑布局中更明显。
解决路径不是“压住它”,而是“隔离它”:
- 原按钮文字必须包在
<span></span>或<div> 里,加载时设 <code>visibility: hidden或display: none(推荐后者,避免占位) - 不要只靠
opacity: 0隐藏文字:透明但仍在文档流,按钮宽度可能突变 - 必须加
role="status"和aria-hidden="true"到spinner-border元素本身,否则读屏器会重复播报 “Loading” - 按钮禁用状态必须同步设
disabled属性,不能只靠样式模拟,否则键盘用户仍可触发
纯 CSS 实现淡入淡出动画的关键细节
直接切 display: none/block 或反复操作 style.opacity 都会卡顿。平滑过渡靠的是 opacity 和 visibility 双属性+延迟配合。
初始状态必须设:
.spinner-border {
opacity: 0;
visibility: hidden;
transition: opacity 0.2s, visibility 0s 0.2s;
}
.spinner-border.showing {
opacity: 1;
visibility: visible;
transition: opacity 0.2s, visibility 0s;
}
JS 只需切换 showing 类名,不要手动操作 style。漏掉 transition-delay 中的 0.2s,淡出时就会闪一下。
容易被忽略的一点:所有涉及 spinner-border 的容器(比如按钮、弹窗遮罩)都必须有明确的 z-index 和 position 上下文,否则在复杂 DOM 层级中,绝对定位的 spinner 可能被兄弟元素遮挡,看起来像“没出现”。


















