Tailwind CSS 核心语法篇 七:过渡和动画

7. 过渡与动画

过渡和动画是为用户界面注入生命力的关键。它们能引导用户的注意力,提供流畅的交互反馈,并极大地提升整体用户体验。Tailwind 提供了一套简洁而强大的工具,用于创建平滑的 CSS 过渡和预设的动画效果,这一章节无需纠结太多,我们会学习一些更成熟的动画库

7.1 过渡 (Transitions)

过渡用于在元素的 状态发生变化时(例如 hoverfocus),平滑地改变其 CSS 属性,而不是瞬间完成。创建过渡效果通常需要组合使用以下四种属性。

7.1.1 核心过渡属性

  1. transition-{property} (过渡属性): 指定 哪些 CSS 属性会应用过渡效果。transition 类是通用选择,包含了最常见的属性。
  2. duration-{amount} (持续时间): 指定过渡效果 花费多长时间duration-300 (300ms) 是一个非常通用的选择。
  3. ease-{curve} (时间函数): 控制过渡的 速度曲线ease-in-out (缓入缓出) 提供了最自然的感觉。
  4. delay-{amount} (延迟): (可选) 指定在过渡 开始前等待 多长时间。
类别常用类名说明
属性transition对颜色、阴影、变换等常用属性启用过渡
属性transition-transform仅对 transform 属性 (如缩放、位移) 启用过渡
时长duration-200200 毫秒,适合快速的 UI 反馈
时长duration-500500 毫秒,适合更舒缓、更明显的动画效果
曲线ease-in-out缓入缓出,动画感觉更自然 (默认)
曲线ease-out缓出,适合元素进入视野的动画
延迟delay-150在 150 毫秒后开始过渡

代码范例:一个典型的悬停过渡效果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Transitions</title>
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="p-8 bg-slate-100 flex items-center justify-center">
<!--
- transition: 启用过渡
- duration-300: 持续时间 300ms
- ease-in-out: 缓入缓出
- hover:*: 定义悬停时的最终状态
-->
<button
class="px-8 py-3 bg-sky-600 text-white font-semibold rounded-lg shadow-md
transition duration-300 ease-in-out
hover:bg-sky-700 hover:scale-110 hover:-translate-y-1"
>
Hover Me
</button>
</body>
</html>

7.1.2 序列动画 (Staggered Animations)

通过为连续的元素设置不同的 delay 值,可以创建出优雅的 序列动画交错动画 效果。这在加载列表项或展示导航菜单时非常有用。

代码范例:悬停时依次出现的列表项

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Staggered Transition</title>
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="p-8 bg-slate-900 flex items-center justify-center">
<!-- 将 group 类添加到父元素上 -->
<div class="group">
<h2 class="text-white text-center mb-4">Hover over me!</h2>
<div class="space-y-2">
<!--
默认情况下,列表项是透明且向右偏移的。
当父元素被悬停时 (group-hover),它们会恢复正常。
每个元素都有不同的 delay,从而创建了序列效果。
-->
<div class="opacity-0 transition duration-500 delay-100 group-hover:opacity-100 group-hover:translate-x-0 translate-x-4 h-8 w-48 bg-white rounded"></div>
<div class="opacity-0 transition duration-500 delay-200 group-hover:opacity-100 group-hover:translate-x-0 translate-x-4 h-8 w-48 bg-white rounded"></div>
<div class="opacity-0 transition duration-500 delay-300 group-hover:opacity-100 group-hover:translate-x-0 translate-x-4 h-8 w-48 bg-white rounded"></div>
</div>
</div>
</body>
</html>

7.2 动画 (Animation)

与过渡不同,动画可以 自动播放、无限循环,并包含更复杂的 关键帧 (@keyframes)。Tailwind 提供了一些开箱即用的实用动画,非常适合用于加载指示器、通知和骨架屏。

常用类名说明适用场景
animate-spin旋转最经典的加载中 (loading) 指示器。
animate-ping脉冲/涟漪用于通知、新消息提示,吸引用户注意。
animate-pulse脉搏/呼吸缓慢地淡入淡出,是创建骨架屏 (skeleton screen) 的完美选择。
animate-bounce弹跳模拟上下弹跳,常用于“向下滚动”的箭头图标。

代码范例:Tailwind 内置动画

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title> Animations </title>
<script src="https://cdn.tailwindcss.com"> </script>
</head>
<body class="p-8">
<div class="grid grid-cols-2 md:grid-cols-4 gap-8 items-center justify-items-center">
<!-- Spin -->
<svg class="animate-spin h-8 w-8 text-sky-500" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"> </circle>
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"> </path>
</svg>
<!-- Ping -->
<span class="relative flex h-6 w-6">
<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-6 w-6 bg-red-500"> </span>
</span>
<!-- Bounce -->
<svg class="animate-bounce w-8 h-8 text-slate-900" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" viewBox="0 0 24 24" stroke="currentColor">
<path d="M19 14l-7 7m0 0l-7-7m7 7V3"> </path>
</svg>
<!-- Pulse -->
<div class="w-full space-y-3">
<div class="h-4 bg-slate-200 rounded animate-pulse"> </div>
<div class="h-4 bg-slate-200 rounded animate-pulse w-5/6"> </div>
</div>
</div>
</body>
</html>