Tailwind CSS 入门教程
动画:内置与自定义
本教程共 50 篇 · 第 37 篇 · 更新于 2026-07-29 · 约 7 分钟阅读
Tailwind CSSTailwind CSS 入门教程动画animation关键帧keyframesanimate-spinanimate-bounce
37. 动画:内置与自定义
本节目标:掌握 Tailwind CSS 内置的四种动画效果,学会通过
@theme指令定义自定义关键帧动画,理解动画与可访问性的关系。
动画和过渡是两回事——过渡需要触发条件(比如 hover),动画可以自己跑、循环、往返。
内置动画
Tailwind 提供了四种开箱即用的动画:
<!-- 旋转动画:适合加载指示器 -->
<svg class="animate-spin w-6 h-6 text-blue-500" viewBox="0 0 24 24">
<circle cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"
fill="none" stroke-dasharray="60" stroke-linecap="round"/>
</svg>
<!-- 弹跳动画:适合提示向下滚动 -->
<div class="animate-bounce">
<svg class="w-6 h-6 mx-auto" fill="none" stroke="currentColor">
<path d="M19 14l-7 7m0 0l-7-7m7 7V3"/>
</svg>
</div>
<!-- 脉冲动画:适合加载占位符 -->
<div class="animate-pulse">
<div class="h-4 bg-gray-300 rounded w-3/4"></div>
<div class="h-4 bg-gray-300 rounded w-1/2 mt-2"></div>
</div>
<!-- 缩放淡出动画:适合通知提示 -->
<span class="relative flex h-3 w-3">
<span class="animate-ping absolute inline-flex h-full w-full rounded-full bg-red-400 opacity-75"></span>
<span class="relative inline-flex rounded-full h-3 w-3 bg-red-500"></span>
</span>
每种动画对应的 CSS 关键帧:
| 类名 | 效果 | 典型用途 |
|---|---|---|
animate-spin | 360度无限旋转 | 加载 spinner |
animate-bounce | 上下弹跳 | 提示箭头 |
animate-pulse | 透明度脉冲 | 骨架屏 |
animate-ping | 缩放+淡出 | 通知红点 |
自定义动画
内置动画满足不了需求时,可以在 @theme 中定义自定义动画:
@import "tailwindcss";
@theme {
/* 定义动画和关键帧 */
--animate-fade-in: fade-in 0.3s ease-out;
--animate-slide-up: slide-up 0.4s ease-out;
--animate-wiggle: wiggle 1s ease-in-out infinite;
@keyframes fade-in {
from { opacity: 0; }
to { opacity: 1; }
}
@keyframes slide-up {
from {
opacity: 0;
transform: translateY(10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@keyframes wiggle {
0%, 100% { transform: rotate(-3deg); }
50% { transform: rotate(3deg); }
}
}
定义完成后,就可以像内置动画一样使用:
<!-- 淡入动画 -->
<div class="animate-fade-in">淡入出现</div>
<!-- 上滑进入 -->
<div class="animate-slide-up">从下方滑入</div>
<!-- 抖动效果 -->
<button class="animate-wiggle">抖动按钮</button>
动画控制
Tailwind 提供了一些控制动画行为的工具类:
<!-- 暂停动画 -->
<div class="animate-spin hover:paused">悬停时暂停</div>
<!-- 动画播放次数(使用任意值) -->
<div class="animate-spin" style="animation-iteration-count: 1">只转一圈</div>
<div class="animate-spin" style="animation-iteration-count: 3">转三圈</div>
实际应用场景
<!-- 1. 骨架屏加载 -->
<div class="animate-pulse space-y-4">
<div class="h-4 bg-gray-200 rounded w-3/4"></div>
<div class="h-4 bg-gray-200 rounded"></div>
<div class="h-4 bg-gray-200 rounded w-5/6"></div>
<div class="h-32 bg-gray-200 rounded"></div>
</div>
<!-- 2. 通知提示(带 ping 效果) -->
<div class="relative">
<button class="p-2">
<svg class="w-6 h-6"><!-- 铃铛图标 --></svg>
</button>
<span class="absolute top-1 right-1 flex h-2 w-2">
<span class="animate-ping absolute inline-flex h-full w-full rounded-full bg-red-400 opacity-75"></span>
<span class="relative inline-flex rounded-full h-2 w-2 bg-red-500"></span>
</span>
</div>
<!-- 3. 模态框入场 -->
<div class="fixed inset-0 bg-black/50 animate-fade-in" data-state="open">
<div class="animate-slide-up bg-white rounded-xl p-6 max-w-md mx-auto mt-20">
<h2 class="text-xl font-bold">标题</h2>
<p class="mt-2">内容</p>
</div>
</div>
<!-- 4. 表单验证错误抖动 -->
<input class="border rounded-lg px-4 py-2 animate-shake"
:class="error && 'border-red-500 animate-wiggle'">
动画与可访问性
动画不是越多越好。有些用户(比如前庭功能障碍者)看到动画会头晕恶心,这是真实存在的可访问性问题。
尊重用户的系统设置——prefers-reduced-motion 媒体查询:
<!-- 只在用户没有开启"减少动画"时播放 -->
<div class="motion-safe:animate-bounce">
尊重用户偏好的弹跳动画
</div>
<!-- 只在用户开启"减少动画"时应用 -->
<div class="motion-reduce:animate-none">
减少动画模式下的替代样式
</div>
Tip设计动画时遵循几个原则:
- 每个动画都应有明确目的,不是装饰
- 保持微妙,过度动画会分散注意力
- 保持一致性,相似元素用相似动画
- 优先使用 transform 和 opacity,性能最好
- 尊重
prefers-reduced-motion用户偏好
动画性能
动画性能上有几个要点:
- 优先用 transform 和 opacity:GPU 加速,不触发布局,丝般顺滑
- 别动画 width/height/top/left:触发重绘,卡到怀疑人生
- will-change 谨慎用:提前告诉浏览器哪些属性会变,但别滥用
- 移动端要更克制:手机性能有限,动画越简单越好
<!-- 高性能动画 -->
<div class="transition-transform duration-300 hover:scale-105">
推荐
</div>
<!-- 低性能动画 -->
<div class="transition-all duration-300 hover:w-40">
不推荐
</div>
动画用好了是加分项,用不好就是减分项。我个人的标准是:如果你做完了动画,用户说”诶这个挺顺”,那就对了;如果用户说”哇这个动画好酷”,那可能做过了。