必须在tailwind.config.js的theme.extend.keyframes和theme.extend.animation中配对注册自定义动画,keyframes定义帧逻辑(百分比须加引号、属性值须为字符串),animation绑定完整声明(含时长、缓动、forwards等),二者动画名须完全一致,缺一不可。

直接在 tailwind.config.js 里写 @keyframes 不生效——Tailwind 不解析 CSS 文件里的关键帧,必须走配置注入。
为什么 animate-spin 不能直接改,得自己配 keyframes?
Tailwind 内置的 animate-spin 固定用 1s ease-linear infinite,且只作用于 transform: rotate()。想换缓动、调时长、加缩放或改旋转轴心,就得定义新动画,而不是覆盖默认类。
-
animate-spin是一个「已注册」的工具类,背后绑定的是 Tailwind 自带的spin关键帧,你无法通过 CSS 覆盖它(除非用!important破坏优先级) - 自定义动画必须从
theme.extend.keyframes开始,否则 Tailwind 完全无视——哪怕你写了@keyframes my-spin在 CSS 里,也进不了构建流程 - 常见错误:把 keyframes 写在
theme.keyframes或顶层对象里,结果 build 后没效果,控制台也不报错
怎么在 tailwind.config.js 中正确定义 keyframes?
必须严格落在 theme.extend.keyframes 下,且每个帧的百分比值要用引号包裹("0%"、"100%"),否则 PostCSS 解析失败,整个 keyframes 被丢弃。
module.exports = {
theme: {
extend: {
keyframes: {
'fade-in': {
'0%': { opacity: '0', transform: 'translateY(10px)' },
'100%': { opacity: '1', transform: 'translateY(0)' }
},
'slow-spin': {
'0%': { transform: 'rotate(0deg)' },
'100%': { transform: 'rotate(360deg)' }
}
},
animation: {
'fade-in': 'fade-in 0.4s ease-out forwards',
'slow-spin': 'slow-spin 2s ease-in-out infinite'
}
}
}
}
-
keyframes里只写样式变化,不写时长、循环或填充模式——这些由animation配置决定 -
animation的值是完整 CSSanimation属性字符串,比如'fade-in 0.4s ease-out forwards',其中forwards很关键,否则动画结束会回退到初始态 - 两个对象里的动画名(如
fade-in)必须完全一致,大小写、连字符都不能错
为什么加了自定义动画类却没反应?
最常踩的坑不是配置错,而是 HTML 元素本身不具备触发条件:没有显式尺寸、display 不兼容、或起始状态和动画第一帧冲突。
立即学习“前端免费学习笔记(深入)”;
- 对
inline元素(如<span>)直接加animate-slow-spin,大概率不动——transform在 inline 元素上受限,得加inline-block或block - 动画第一帧是
opacity: 0,但元素 HTML 里没设opacity-0,就会跳变——得手动预设起始样式:opacity-0 animate-fade-in - SVG 用
animate-slow-spin时,如果viewBox和实际width/height不匹配,旋转中心偏移,看起来像抖动而非纯转 - DevTools 的 Animations 面板打不开?确认浏览器支持(Chrome/Firefox 最新版),且元素已渲染、class 已存在、没被
display: none拦截
真正麻烦的不是写几行配置,而是动画和 DOM 状态的耦合:class 切换时机、是否需要 forwards 保持终态、SVG 坐标系干扰、以及 inline 元素那点隐式行为——这些没法靠重试解决,得对着 DevTools 一帧一帧看。


















