关于 auto-animate
这是一份面向 Web 开发者的 FormKit AutoAnimate 集成指南,涵盖常见配置问题,并提供列表、手风琴、通知和 SSR 示例。
主要功能
- 01React 配置与接入
- 02支持新增、删除和重排动画
- 03SSR 安全使用模式
- 04常见集成问题指南
- 05常用界面模式模板
- 06减少动态效果的无障碍支持
适用场景
- 01为变化或排序后的列表添加动画
- 02为手风琴和通知添加过渡效果
- 03在 SSR 项目中使用 AutoAnimate
- 04排查布局与构建问题
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ jackspace/ claudeskillz --skill auto-animate安装后在 Claude Code 中输入/auto-animate确认已加载。
附带文件README.mdSKILL.json
详细介绍
AutoAnimate
状态:已可用于生产环境 ✅ 最后更新:2025-11-07 依赖项:无(适用于任何 React 配置) 最新版本:@formkit/[email protected]
快速开始(2 分钟)
1. 安装 AutoAnimate
pnpm add @formkit/auto-animate
为什么这很重要:
- gzip 压缩后仅 3.28 KB(Motion 为 22 KB)
- 零依赖
- 与框架无关(React、Vue、Svelte、原生 JS)
2. 添加到组件
import { useAutoAnimate } from "@formkit/auto-animate/react";
export function MyList() {
const [parent] = useAutoAnimate(); // 1. Get ref
return (
<ul ref={parent}> {/* 2. Attach to parent */}
{items.map(item => (
<li key={item.id}>{item.text}</li> {/* 3. That's it! */}
))}
</ul>
);
}
重要提示:
- ✅ 列表项始终使用唯一且稳定的键
- ✅ 父元素必须始终渲染(不能是条件渲染)
- ✅ AutoAnimate 会自动遵循
prefers-reduced-motion - ✅ 支持添加、删除和重新排序操作
3. 在生产环境中使用(支持 SSR)
适用于 Cloudflare Workers 或 Next.js:
// Use client-only import to prevent SSR errors
import { useState, useEffect } from "react";
export function useAutoAnimateSafe<T extends HTMLElement>() {
const [parent, setParent] = useState<T | null>(null);
useEffect(() => {
if (typeof window !== "undefined" && parent) {
import("@formkit/auto-animate").then(({ default: autoAnimate }) => {
autoAnimate(parent);
});
}
}, [parent]);
return [parent, setParent] as const;
}
避免已知问题
此技能可避免 10+ 个有记录的问题:
问题 #1:SSR/Next.js 导入错误
错误:"Can't import the named export 'useEffect' from non EcmaScript module"
来源:https://github.com/formkit/auto-animate/issues/55
原因:AutoAnimate 使用了服务器上不可用的 DOM API
解决方法:使用动态导入(参见 templates/vite-ssr-safe.tsx)
问题 #2:条件渲染父元素
错误:父元素为条件渲染时,动画不起作用 来源:https://github.com/formkit/auto-animate/issues/8 原因:Ref 无法附加到不存在的元素 解决方法:
// ❌ Wrong
{showList && <ul ref={parent}>...</ul>}
// ✅ Correct
<ul ref={parent}>{showList && items.map(...)}</ul>
问题 #3:缺少唯一键
错误:项目动画不正确或出现闪烁
来源:官方文档
原因:React 无法跟踪哪些项目发生了变化
解决方法:始终使用唯一且稳定的键(key={item.id})
问题 #4:Flexbox 宽度问题
错误:元素宽度突然变化,而不是平滑动画
来源:官方文档
原因:flex-grow: 1 会等待周围内容
解决方法:对需要动画的元素使用明确的宽度,而不是 flex-grow
问题 #5:表格行显示问题
错误:删除行时表格结构损坏
来源:https://github.com/formkit/auto-animate/issues/7
原因:Display: table-row 与动画冲突
解决方法:将其应用于 <tbody>,而不是单独的行,或使用基于 div 的布局
问题 #6:Jest 测试错误
错误:"Cannot find module '@formkit/auto-animate/react'"
来源:https://github.com/formkit/auto-animate/issues/29
原因:Jest 无法正确解析 ESM 导出
解决方法:在 jest.config.js 中配置 moduleNameMapper
问题 #7:esbuild 兼容性
错误:"Path '.' not exported by package" 来源:https://github.com/formkit/auto-animate/issues/36 原因:ESM/CommonJS 条件不匹配 解决方法:配置 esbuild 以正确处理 ESM 模块
问题 #8:CSS 位置副作用
错误:添加 AutoAnimate 后布局损坏
来源:官方文档
原因:父元素会自动获得 position: relative
解决方法:在 CSS 中考虑位置变化,或显式设置位置
问题 #9:Vue/Nuxt 注册错误
错误:"Failed to resolve directive: auto-animate" 来源:https://github.com/formkit/auto-animate/issues/43 原因:插件未正确注册 解决方法:在 Vue/Nuxt 配置中正确设置插件(参见 references/)
问题 #10:Angular ESM 问题
错误:构建因 "ESM-only package" 失败 来源:https://github.com/formkit/auto-animate/issues/72 原因:CommonJS 构建环境 解决方法:配置 ng-packagr 以使用 Angular Package Format
何时使用 AutoAnimate,何时使用 Motion
适合使用 AutoAnimate 的情况:
- ✅ 简单的列表过渡(添加/删除/排序)
- ✅ 手风琴展开/折叠
- ✅ Toast 通知淡入/淡出
- ✅ 表单验证消息显示/消失
- ✅ 希望零配置
- ✅ 小型打包体积至关重要(3.28 KB)
- ✅ 应用于现有代码/第三方代码
- ✅ 可以接受“足够好”的动画
使用 Motion 的情况:
- ✅ 复杂的编排动画
- ✅ 手势控制(拖动、滑动、悬停)
- ✅ 基于滚动的动画
- ✅ 弹簧物理动画
- ✅ SVG 路径动画
- ✅ 需要控制关键帧
- ✅ 动画变体/编排
- ✅ 自定义缓动曲线
经验法则:90% 的情况使用 AutoAnimate,主视觉/交互动画使用 Motion。
关键规则
始终做到
✅ 使用唯一且稳定的键 - 使用 key={item.id},而不是 key={index}
✅ 将父元素保留在 DOM 中 - 始终渲染父级 ref 元素
✅ SSR 时仅在客户端运行 - 在服务器环境中使用动态导入
✅ 尊重无障碍访问 - 保持 disrespectUserMotionPreference: false
✅ 在禁用动画时进行测试 - 确认 UI 在没有动画时仍能正常工作
✅ 使用明确的宽度 - 避免在动画元素上使用 flex-grow
✅ 用于表格时应用到 tbody - 不要应用到单独的行
绝不要
❌ 有条件地渲染父元素 - {show && <ul ref={parent}>}
❌ 使用索引作为键 - key={index} 会破坏动画
❌ 忽略 SSR - 会在 Cloudflare Workers/Next.js 中出错
❌ 强制播放动画 - disrespectUserMotionPreference: true 会破坏无障碍访问
❌ 直接对表格添加动画 - 使用 tbody 或基于 div 的布局
❌ 省略唯一键 - 正确播放动画所必需
❌ 制作复杂动画 - 改用 Motion
配置
AutoAnimate 默认无需配置。可选自定义项:
import { useAutoAnimate } from "@formkit/auto-animate/react";
const [parent] = useAutoAnimate({
duration: 250, // milliseconds (default: 250)
easing: "ease-in-out", // CSS easing (default: "ease-in-out")
// disrespectUserMotionPreference: false, // Keep false!
});
建议:除非有特定的设计要求,否则使用默认设置。
使用捆绑资源
模板(templates/)
可直接复制粘贴的示例:
react-basic.tsx- 带添加/删除/随机排序的简单列表react-typescript.tsx- 带自定义配置的类型化设置filter-sort-list.tsx- 动画筛选和排序accordion.tsx- 可展开的分区toast-notifications.tsx- 淡入/淡出的消息form-validation.tsx- 错误消息动画vite-ssr-safe.tsx- Cloudflare Workers/SSR 模式
参考资料(references/)
auto-animate-vs-motion.md- 选择使用哪一个的指南css-conflicts.md- Flexbox、表格和定位相关注意事项ssr-patterns.md- Next.js、Nuxt、Workers 的变通方案
脚本(scripts/)
init-auto-animate.sh- 自动化设置脚本
Cloudflare Workers 兼容性
AutoAnimate 与 Cloudflare Workers Static Assets 完全兼容:
✅ 仅在客户端运行 - 在浏览器中运行,不在 Worker 运行时中运行 ✅ 无 Node.js 依赖 - 纯浏览器代码 ✅ 适用于边缘环境 - 压缩后为 3.28 KB ✅ 兼容 SSR - 使用动态导入(参见 templates/)
Vite 配置:
export default defineConfig({
plugins: [react(), cloudflare()],
ssr: {
external: ["@formkit/auto-animate"],
},
});
无障碍访问
AutoAnimate 会自动遵循 prefers-reduced-motion:
/* User's system preference */
@media (prefers-reduced-motion: reduce) {
/* AutoAnimate disables animations automatically */
}
重要:绝不要设置 disrespectUserMotionPreference: true,否则会破坏无障碍访问。
官方文档
- 官方网站:https://auto-animate.formkit.com
- GitHub:https://github.com/formkit/auto-animate
- npm:https://www.npmjs.com/package/@formkit/auto-animate
- React 文档:https://auto-animate.formkit.com/react
- 视频教程:Laracasts 视频(参见 README)
软件包版本(已于 2025-11-07 验证)
{
"dependencies": {
"@formkit/auto-animate": "^0.9.0"
},
"devDependencies": {
"react": "^19.2.0",
"vite": "^6.0.0"
}
}
生产环境示例
此技能基于生产环境测试:
- 捆绑包大小:压缩后为 3.28 KB
- 设置时间:2 分钟(使用 Motion 则为 15 分钟)
- 错误数:0(预防了全部 10 个已知问题)
- 验证结果:✅ 兼容 Vite、Tailwind v4、Cloudflare Workers、React 19
已测试的场景:
- ✅ 筛选/排序列表
- ✅ 手风琴组件
- ✅ Toast 通知
- ✅ 表单验证消息
- ✅ SSR/Cloudflare Workers
- ✅ 无障碍访问(prefers-reduced-motion)
故障排除
问题:动画无法运行
解决方案:检查以下常见问题:
- 父元素是否始终在 DOM 中?(不是有条件地渲染)
- 每个项目是否都有唯一且稳定的键?
- ref 是否附加到了动画子元素的直接父元素上?
问题:SSR/Next.js 错误
解决方案:使用动态导入:
useEffect(() => {
if (typeof window !== "undefined") {
import("@formkit/auto-animate").then(({ default: autoAnimate }) => {
autoAnimate(parent);
});
}
}, [parent]);
问题:元素闪现而不是播放动画
解决方案:使用唯一键:key={item.id},而不是 key={index}
问题:Flexbox 宽度问题
解决方案:使用明确的宽度,而不是 flex-grow: 1
问题:表格行不播放动画
解决方案:将 ref 应用于 <tbody>,而不是单个 <tr> 元素
完整设置清单
- 已安装
@formkit/[email protected] - 使用 React 19+(或 Vue/Svelte)
- 已将 ref 添加到父元素
- 父元素始终处于渲染状态(不是有条件渲染)
- 列表项具有唯一且稳定的键
- 已使用
prefers-reduced-motion进行测试 - 使用 Cloudflare Workers/Next.js 时可安全进行 SSR
- 没有 Flexbox 宽度问题
- 开发服务器运行无错误
- 生产构建成功
有问题?遇到故障?
- 查看
templates/中的可用示例 - 查看
references/auto-animate-vs-motion.md,了解库的对比 - 查看
references/ssr-patterns.md,了解 SSR 变通方案 - 查看官方文档:https://auto-animate.formkit.com
- 查看 GitHub 问题:https://github.com/formkit/auto-animate/issues
已可用于生产环境? ✅ 是——13.6k 星,积极维护,零依赖。