Tailwind自定义动画必须在theme.extend.keyframes和theme.extend.animation中严格配对注册,键名完全一致、百分比加引号、属性值为字符串、animation声明含forwards及可变时长,缺一则animate-类静默失效。

自定义关键帧在 Tailwind 里不是“写完就生效”,必须配对注册 keyframes 和 animation,漏掉任一环节,animate-xxx 类根本不会生成 CSS 规则——浏览器控制台也不报错,只是静默失效。
tailwind.config.js 中 keyframes 的合法写法
必须严格放在 theme.extend.keyframes 下,键名用引号包裹(如 'slide-in'),帧百分比也必须加引号:'0%'、'100%' 或 'from'、'to';不能写成 0 或 from(不加引号)。
- 属性名必须是标准可动画 CSS 属性:✅
transform、opacity、color;❌translateX、scale这类独立变换函数不被识别 - 所有值必须是字符串:
'0%': { opacity: '0.2' }✅,opacity: 0.2❌(会被跳过) - 多帧逻辑要完整覆盖起止:
'0%'、'50%'、'100%'可以共存,但不能缺首尾
animation 配置必须与 keyframes 名字完全一致
theme.extend.animation 里的键名(如 'fade-in')必须和 keyframes 里的键名逐字符一致:大小写、连字符、引号都不能差。否则 HTML 中写 animate-fade-in 也不会触发任何样式。
- 值必须是完整的 CSS
animation声明字符串,例如:'fade-in 0.4s ease-out forwards' -
forwards极易被漏掉:没有它,动画播完会立刻回退到初始态(比如从opacity: 0→1,播完又变回0,看起来像“闪一下”) - 若需支持
duration-300等变体,时长不能写死:'my-spin var(--tw-animation-duration, 1s) linear infinite'✅,'my-spin 2s linear infinite'❌(duration-300将无效)
HTML 中动起来前,得先匹配首帧状态
动画不会“凭空开始”。如果关键帧首帧是 '0%': { opacity: '0', transform: 'scale(0.8)' },那元素本身就得有对应初始样式,否则第一帧会跳变或卡住。
立即学习“前端免费学习笔记(深入)”;
- 推荐显式加基础类:
opacity-0 scale-[0.8],而不是依赖内联style - SVG 路径动画更敏感:必须手动设
stroke-dasharray和stroke-dashoffset初始值,且与关键帧首尾帧数值一致 - 用
group-hover触发的动画,也要确保父容器有class="group",且 hover 区域可交互(比如不能是display: contents或pointer-events: none)
最常被忽略的是三件事:首帧样式没对齐、forwards 没写、keyframes 和 animation 键名大小写不一致——这三处任一出错,动画都“看起来没动”,但查 DOM 和样式面板根本找不到对应 CSS 规则。



















