首页 / Tailwind CSS 入门教程 / 动画:内置与自定义

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-spin360度无限旋转加载 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

设计动画时遵循几个原则:

  1. 每个动画都应有明确目的,不是装饰
  2. 保持微妙,过度动画会分散注意力
  3. 保持一致性,相似元素用相似动画
  4. 优先使用 transform 和 opacity,性能最好
  5. 尊重 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>

动画用好了是加分项,用不好就是减分项。我个人的标准是:如果你做完了动画,用户说”诶这个挺顺”,那就对了;如果用户说”哇这个动画好酷”,那可能做过了。