自定义 keyframes 必须放在 theme.extend.keyframes 下,键为字符串如 '0%' 或 'from',值需用标准 CSS 属性名(如 transform: 'translateX(-100%)'),属性值必须是字符串;animation 声明需完整且格式正确,duration 单位须为 ms 或 s,animate-类生效需避免初始隐藏覆盖动画起始态。

必须把自定义 keyframes 放在 theme.extend.keyframes 下,写错位置或语法不合法,动画根本不会生成 CSS 规则。
keyframes 必须用字符串键(如 '0%' 或 'from'),值必须是对象
很多人直接写 '0%': { translateX: '-100%' },这会静默失败——Tailwind 不识别独立的 translateX 属性,只认标准 CSS 属性名。CSS transform 是一个复合声明,不能拆开。
-
'0%': { transform: 'translateX(-100%)' }✅ 正确 -
'0%': { translateX: '-100%' }❌ 无效,会被忽略 -
'from'和'to'可以代替'0%'/'100%',但不能混用'from'和'50%' - 属性值必须是字符串(如
opacity: '0.3'),不能是数字(opacity: 0.3)
animation 工具类绑定要严格匹配 duration 和 timing-function 格式
theme.extend.animation 里的值不是 CSS @keyframes 名,而是完整的动画声明字符串,格式为:'name': 'keyframes-name duration timing-function [iteration-count] [direction] [fill-mode]'。Tailwind 会把它原样塞进 animation CSS 属性里。
-
fadeIn: 'fadeIn 300ms ease-in forwards'✅ 有效,forwards保证结束状态保留 -
fadeIn: 'fadeIn 0.3s'❌ 缺少 timing-function,浏览器可能用默认ease,但行为不可控 - duration 单位必须是
ms或s,300(无单位)会被忽略 - 如果要用
infinite,记得加引号:'spin-slow 2s linear infinite'
animate-类生效的前提:元素不能初始隐藏
比如你定义了 appear 动画让 opacity 从 0 → 1,但如果元素本身带 opacity-0 或 hidden,动画一触发就“卡住”在起点——因为 opacity: 0 已被其他 class 覆盖,keyframes 的 '0%': { opacity: '0' } 就没机会起效。
- 正确做法:移除初始
opacity-0,靠动画自己控制起始态 - 或者用
opacity-0 animate-appearance,但必须确保animate-appearance的forwards填充模式生效 - 更稳妥的加载动画方案:配合
IntersectionObserver,等元素进入视口再加animate-xxx类,避免页面一加载就全播
最容易被忽略的是 keyframes 值的合法性检查——Tailwind 不报错,只跳过非法项。建议每次加完配置后,运行 npx tailwindcss -o ./dist/tailwind.css --minify 并搜索生成的 CSS 文件里有没有对应 @keyframes xxx,没有就是配置写错了。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











