Tailwind自定义动画序列:配置文件扩展keyframes与animation
先说一个基础规则:在 Tailwind 中自定义动画时,所有 keyframes 定义都必须放在 theme.extend.keyframes 下,不能直接放在 theme.keyframes 或更顶层。每个 keyframe 是一个对象,其中的状态键要用字符串形式(例如 '0%' 或 'from'
theme.extend.keyframes 下,不能直接放在 theme.keyframes 或更顶层。每个 keyframe 是一个对象,其中的状态键要用字符串形式(例如 '0%' 或 'from'),对应的值也必须是对象。CSS 属性必须写完整,比如 transform: 'translateX(0)',而 translateX: '0' 这种单独写法是无效的。

在配置文件中扩展 keyframes
很多新手在这里容易出错,比如写成 '0%': { translateX: '-100%' } —— Tailwind 不会识别这种写法,因为 translateX 不是独立的 CSS 属性,必须包裹在 transform 字符串中:
keyframes: {
'slide-in': {
'0%': { transform: 'translateX(-100%)' },
'100%': { transform: 'translateX(0)' }
}
}
这里有几点细节需要注意:
- 百分比写法(
'0%'/'100%')和关键词写法('from'/'to')都支持,但不能混用,否则容易导致奇怪的问题 - 动画中用到的 CSS 属性,要确保 Tailwind 对应的功能已开启。比如
transform和transition默认支持,无需额外配置 - 如果使用了
filter或backdrop-filter等属性,需要检查plugins中是否启用了对应插件
把 keyframes 绑定为可用的动画工具类
仅有 keyframes 还不够,必须在 theme.extend.animation 中将其注册成一个工具类名。格式固定:'工具类名': 'keyframes名 持续时间 缓动函数',这个字符串就是最终生成的 animation CSS 属性值。
例如:
animation: {
'slide-in': 'slide-in 0.4s ease-out',
'fade-up': 'fade-up 0.5s cubic-bezier(0.22, 0.61, 0.36, 1)'
}
几个关键点:
- 工具类名(比如
slide-in)就是之后在 HTML 中使用的名称,但使用时前面要加animate-前缀,写成animate-slide-in - 持续时间必须带单位,
s或ms都可以,但纯数字(如400)不会生效,建议统一使用s,避免混淆 - 缓动函数可以使用预设值(
ease-in、linear),也可以自定义贝塞尔曲线 - 注意:在
animation的值中不能写infinite或forwards这类属性,它们需通过额外的类(如animate-infinite)或行内 style 来补充
为什么动画类写了却没反应
这是最常见的问题。许多人认为加上 animate-slide-in 就万事大吉,其实不然。Tailwind 的 animate- 类只声明了动画,播放时机还需要自己控制。
- 希望页面加载时自动播放?元素必须一开始就是可见的,不能是
hidden或opacity-0且周围没有显示逻辑 - 如果想在进入视口时播放,需要配合
animate-in(这个类来自tailwindcss-animate插件),此时animate-slide-in才会被识别为进入动画 - 如果使用原生方式,请检查元素是否被
animation-play-state: paused暂停,通过 DevTools 查看 computed styles 可以发现 - 最直接的方法:在浏览器 DevTools 中查看元素的
animation属性,确认它是否被正确应用,有没有被其他样式覆盖
duration 和 delay 工具类如何配合使用
duration- 和 delay- 是独立于 animation 声明的工具类,且优先级更高,会直接覆盖在 animation 中设置的时长和延迟。例如:
这段代码的含义很明确:原本 slide-in 动画的时长为 0.4s,现在被覆盖为 0.7s,并且延迟 200ms 才开始。
使用时的要点:
- 预设的
duration-类(如duration-300)在theme.extend.animationDuration中定义。如果不自定义,只能使用内置的几个值:75、100、150……直到1000 - 任意值语法
duration-[650ms]可以绕过预设限制,但需谨慎使用。如果大量使用不同的任意值,容易被 PurgeCSS 误删(虽然构建时不会被移除,但过多会增加管理难度) delay-同理,不过它只影响单次动画的开始时间。对于设为animation-iteration-count: infinite的循环动画,延迟仅影响第一轮,后续轮次不再起作用
要实现真正的序列动画,关键不在于单个动画内部的时间切分,而在于不同元素之间 delay- 值的差值。让几个元素依次加上 delay-100、delay-200、delay-300,效果就自然呈现了——这才是正确做法。
