需手写@keyframes实现匀速循环、可调速、支持反向的旋转动画,配合border+rounded-full构建轻量环形Loading,并注意transform-origin、响应式与主题色适配。

用 @keyframes 定义旋转动画,别依赖插件
Tailwind 默认不带 animate-spin 以外的旋转动画,想实现「匀速循环+可调速+支持反向」,必须手写 @keyframes。直接在 @layer utilities 或全局 CSS 文件里加一段即可,不用装额外包。
常见错误是把动画写在 div 标签里用内联 style,这会破坏 Tailwind 的原子类习惯,也难复用。正确做法是注册一个自定义动画名,再用 animate-xxx 调用。
示例(放在 src/css/app.css 中):
@layer utilities {
@keyframes spin-slow {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
@keyframes spin-reverse {
from { transform: rotate(0deg); }
to { transform: rotate(-360deg); }
}
.animate-spin-slow {
animation: spin-slow 2s linear infinite;
}
.animate-spin-reverse {
animation: spin-reverse 1.5s linear infinite;
}
}
用 border + rounded-full 拼出环形 Loading
纯 CSS 实现旋转图标最轻量的方式是用边框模拟圆环,而不是 SVG 或字体图标——它体积小、无网络请求、缩放不失真。
立即学习“前端免费学习笔记(深入)”;
关键点在于:必须同时设置 border 和透明色边框,否则旋转时会看到“方块拖影”;border-radius: 9999px(即 rounded-full)要配合足够大的 border-width 才能显形。
- 外层容器设固定宽高(如
w-8 h-8),避免布局抖动 - 用
border-t-transparent隐藏上边框,只留三边形成“缺口环”,更符合 Loading 视觉习惯 - 加上
border-t-color(如border-t-blue-500)控制颜色,比border全写更灵活
完整类名示例:
<div class="w-8 h-8 border-4 border-t-transparent border-blue-500 rounded-full animate-spin-slow"></div>
注意 transform-origin 影响旋转中心点
默认 transform-origin: center 是对的,但如果你给元素加了 margin、padding 或父容器用了 flex/grid 对齐,可能让视觉旋转中心偏移。这时不能靠调 margin 补偿,而应显式重置原点。
Tailwind v3.3+ 支持 origin-center,v3.2 及以下需手写 utility 或直接加 style="transform-origin: center;"。
容易踩的坑:
- 用
animate-spin时没配origin-center,结果图标绕左上角转 - 在
relative容器里嵌套旋转元素,又没设inset-0居中,导致旋转轴错位 - 用
scale缩放旋转元素后,transform-origin仍按原始尺寸计算,需同步调整
响应式下慎用固定 animation-duration
移动端屏幕小、性能弱,2s 旋转在桌面看着流畅,在低端安卓机上可能卡顿或显得太慢。不要在所有设备上硬写死 2s。
推荐方案是用 md:animate-spin-slow 这类断点类,或通过 JS 动态切换类名(比如检测 matchMedia('(prefers-reduced-motion)') 后降级为 animate-pulse)。
另一个现实问题:某些企业内网环境禁用 JS,那就得靠 CSS 媒体查询兜底:
@media (prefers-reduced-motion: reduce) {
.animate-spin-slow {
animation: none;
}
}
真正麻烦的是动画与主题色联动——比如深色模式下 border-blue-500 变成灰色,但没人会为 Loading 图标单独写一套 dark:border-indigo-400,这时候不如用 border-current 继承文字色,再统一设 text-indigo-500 控制。


















