auto-animate
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseAutoAnimate - Error Prevention Guide
AutoAnimate - 错误预防指南
Package: @formkit/auto-animate@0.9.0 (current)
Frameworks: React, Vue, Solid, Svelte, Preact
Last Updated: 2026-01-21
包:@formkit/auto-animate@0.9.0(当前版本)
支持框架:React、Vue、Solid、Svelte、Preact
最后更新:2026-01-21
SSR-Safe Pattern (Critical for Cloudflare Workers/Next.js)
SSR安全模式(对Cloudflare Workers/Next.js至关重要)
tsx
// 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;
}Why this matters: Prevents Issue #1 (SSR/Next.js import errors). AutoAnimate uses DOM APIs not available on server.
tsx
// 使用仅客户端导入以避免SSR错误
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;
}为什么这很重要:可预防问题#1(SSR/Next.js导入错误)。AutoAnimate使用了服务器端不可用的DOM API。
Known Issues Prevention (15 Documented Errors)
已知问题预防(15种已记录错误)
This skill prevents 15 documented issues:
本指南可预防15种已记录的问题:
Issue #1: SSR/Next.js Import Errors
问题#1:SSR/Next.js导入错误
Error: "Can't import the named export 'useEffect' from non EcmaScript module"
Source: https://github.com/formkit/auto-animate/issues/55
Why It Happens: AutoAnimate uses DOM APIs not available on server
Prevention: Use dynamic imports (see )
templates/vite-ssr-safe.tsx错误信息:"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.tsxIssue #2: Conditional Parent Rendering
问题#2:条件父元素渲染
Error: Animations don't work when parent is conditional
Source: https://github.com/formkit/auto-animate/issues/8
Why It Happens: Ref can't attach to non-existent element
Prevention:
React Pattern:
tsx
// ❌ Wrong
{showList && <ul ref={parent}>...</ul>}
// ✅ Correct
<ul ref={parent}>{showList && items.map(...)}</ul>Vue.js Pattern:
vue
<!-- ❌ Wrong - parent conditional -->
<ul v-if="showList" ref="parent">
<li v-for="item in items" :key="item.id">{{ item.text }}</li>
</ul>
<!-- ✅ Correct - children conditional -->
<ul ref="parent">
<li v-if="showList" v-for="item in items" :key="item.id">
{{ item.text }}
</li>
</ul>Source: React Issue #8, Vue Issue #193
错误表现:当父元素为条件渲染时,动画无法正常工作
来源:https://github.com/formkit/auto-animate/issues/8
问题原因:Ref无法绑定到不存在的元素
解决方法:
React 模式:
tsx
// ❌ 错误写法
{showList && <ul ref={parent}>...</ul>}
// ✅ 正确写法
<ul ref={parent}>{showList && items.map(...)}</ul>Vue.js 模式:
vue
<!-- ❌ 错误写法 - 父元素条件渲染 -->
<ul v-if="showList" ref="parent">
<li v-for="item in items" :key="item.id">{{ item.text }}</li>
</ul>
<!-- ✅ 正确写法 - 子元素条件渲染 -->
<ul ref="parent">
<li v-if="showList" v-for="item in items" :key="item.id">
{{ item.text }}
</li>
</ul>来源:React Issue #8,Vue Issue #193
Issue #3: Missing Unique Keys
问题#3:缺少唯一Key
Error: Items don't animate correctly or flash
Source: Official docs
Why It Happens: React can't track which items changed
Prevention: Always use unique, stable keys ()
key={item.id}错误表现:元素动画异常或闪烁
来源:官方文档
问题原因:React无法追踪元素的变化
解决方法:始终使用唯一且稳定的Key()
key={item.id}Issue #4: Flexbox Width and Shaking Issues
问题#4:Flexbox宽度与抖动问题
Error: Elements snap to width instead of animating smoothly, or container shakes on remove
Source: Official docs, Issue #212
Why It Happens: waits for surrounding content, causing timing issues
Prevention: Use explicit width instead of flex-grow for animated elements
flex-grow: 1tsx
// ❌ Wrong - causes shaking
<ul ref={parent} style={{ display: 'flex' }}>
{items.map(item => (
<li key={item.id} style={{ flex: '1 1 auto' }}>{item.text}</li>
))}
</ul>
// ✅ Correct - fixed sizes
<ul ref={parent} style={{ display: 'flex', gap: '1rem' }}>
{items.map(item => (
<li
key={item.id}
style={{ minWidth: '200px', maxWidth: '200px' }}
>
{item.text}
</li>
))}
</ul>Maintainer Note: justin-schroeder confirmed fixed sizes are required for flex containers
错误表现:元素直接跳转到目标宽度而非平滑动画,或移除元素时容器抖动
来源:官方文档,Issue #212
问题原因:会等待周围内容加载,导致时序问题
解决方法:为动画元素使用明确宽度而非flex-grow
flex-grow: 1tsx
// ❌ 错误写法 - 导致抖动
<ul ref={parent} style={{ display: 'flex' }}>
{items.map(item => (
<li key={item.id} style={{ flex: '1 1 auto' }}>{item.text}</li>
))}
</ul>
// ✅ 正确写法 - 固定尺寸
<ul ref={parent} style={{ display: 'flex', gap: '1rem' }}>
{items.map(item => (
<li
key={item.id}
style={{ minWidth: '200px', maxWidth: '200px' }}
>
{item.text}
</li>
))}
</ul>维护者说明:justin-schroeder确认flex容器需要使用固定尺寸
Issue #5: Table Row Display Issues
问题#5:表格行显示异常
Error: Table structure breaks when removing rows
Source: https://github.com/formkit/auto-animate/issues/7
Why It Happens: Display: table-row conflicts with animations
Prevention: Apply to instead of individual rows, or use div-based layouts
<tbody>错误表现:移除行时表格结构破坏
来源:https://github.com/formkit/auto-animate/issues/7
问题原因:Display: table-row与动画冲突
解决方法:将动画应用于而非单独行,或使用基于div的布局
<tbody>Issue #6: Jest Testing Errors
问题#6:Jest测试错误
Error: "Cannot find module '@formkit/auto-animate/react'"
Source: https://github.com/formkit/auto-animate/issues/29
Why It Happens: Jest doesn't resolve ESM exports correctly
Prevention: Configure in jest.config.js
moduleNameMapper错误信息:"Cannot find module '@formkit/auto-animate/react'"
来源:https://github.com/formkit/auto-animate/issues/29
问题原因:Jest无法正确解析ESM导出
解决方法:在jest.config.js中配置
moduleNameMapperIssue #7: esbuild Compatibility
问题#7:esbuild兼容性问题
Error: "Path '.' not exported by package"
Source: https://github.com/formkit/auto-animate/issues/36
Why It Happens: ESM/CommonJS condition mismatch
Prevention: Configure esbuild to handle ESM modules properly
错误信息:"Path '.' not exported by package"
来源:https://github.com/formkit/auto-animate/issues/36
问题原因:ESM/CommonJS条件不匹配
解决方法:配置esbuild以正确处理ESM模块
Issue #8: CSS Position Side Effects
问题#8:CSS定位副作用
Error: Layout breaks after adding AutoAnimate
Source: Official docs
Why It Happens: Parent automatically gets
Prevention: Account for position change in CSS or set explicitly
position: relative错误表现:添加AutoAnimate后布局破坏
来源:官方文档
问题原因:父元素会自动设置
解决方法:在CSS中考虑定位变化或显式设置定位
position: relativeIssue #9: Vue/Nuxt Registration Errors
问题#9:Vue/Nuxt注册错误
Error: "Failed to resolve directive: auto-animate"
Source: https://github.com/formkit/auto-animate/issues/43
Why It Happens: Plugin not registered correctly
Prevention: Proper plugin setup in Vue/Nuxt config (see references/)
Nuxt 3 Note: Requires v0.8.2+ (April 2024). Earlier versions have ESM import issues fixed by Daniel Roe. See Issue #199
错误信息:"Failed to resolve directive: auto-animate"
来源:https://github.com/formkit/auto-animate/issues/43
问题原因:插件未正确注册
解决方法:在Vue/Nuxt配置中正确设置插件(参考references/)
Nuxt 3 注意事项:需要v0.8.2+版本(2024年4月)。早期版本的ESM导入问题已由Daniel Roe修复。参考Issue #199
Issue #10: Angular ESM Issues
问题#10:Angular ESM问题
Error: Build fails with "ESM-only package"
Source: https://github.com/formkit/auto-animate/issues/72
Why It Happens: CommonJS build environment
Prevention: Configure ng-packagr for Angular Package Format
错误表现:构建失败,提示"ESM-only package"
来源:https://github.com/formkit/auto-animate/issues/72
问题原因:CommonJS构建环境
解决方法:配置ng-packagr以适配Angular包格式
Issue #11: React 19 StrictMode Double-Call Bug
问题#11:React 19 StrictMode双调用漏洞
Error: Child animations don't work in React 19 StrictMode
Source: https://github.com/formkit/auto-animate/issues/232
Why It Happens: StrictMode calls useEffect twice, triggering autoAnimate initialization twice
Prevention: Use ref to track initialization
tsx
// ❌ Wrong - breaks in StrictMode
const [parent] = useAutoAnimate();
// ✅ Correct - prevents double initialization
const [parent] = useAutoAnimate();
const initialized = useRef(false);
useEffect(() => {
if (initialized.current) return;
initialized.current = true;
}, []);Note: React 19 enables StrictMode by default in development. This affects all React 19+ projects.
错误表现:在React 19 StrictMode中子元素动画无法工作
来源:https://github.com/formkit/auto-animate/issues/232
问题原因:StrictMode会调用useEffect两次,导致autoAnimate初始化两次
解决方法:使用ref跟踪初始化状态
tsx
// ❌ 错误写法 - 在StrictMode中失效
const [parent] = useAutoAnimate();
// ✅ 正确写法 - 避免重复初始化
const [parent] = useAutoAnimate();
const initialized = useRef(false);
useEffect(() => {
if (initialized.current) return;
initialized.current = true;
}, []);注意:React 19在开发环境中默认启用StrictMode。这会影响所有React 19+项目。
Issue #12: Broken Animation Outside Viewport
问题#12:视口外动画失效
Error: Animations broken when list is outside viewport
Source: https://github.com/formkit/auto-animate/issues/222
Why It Happens: Chrome may not run Animation API for off-screen elements
Prevention: Ensure parent is visible before applying autoAnimate
tsx
const isInViewport = (element) => {
const rect = element.getBoundingClientRect();
return rect.top >= 0 && rect.bottom <= window.innerHeight;
};
useEffect(() => {
if (parent.current && isInViewport(parent.current)) {
autoAnimate(parent.current);
}
}, [parent]);错误表现:当列表位于视口外时动画失效
来源:https://github.com/formkit/auto-animate/issues/222
问题原因:Chrome可能不会对屏幕外元素运行动画API
解决方法:确保父元素可见后再应用autoAnimate
tsx
const isInViewport = (element) => {
const rect = element.getBoundingClientRect();
return rect.top >= 0 && rect.bottom <= window.innerHeight;
};
useEffect(() => {
if (parent.current && isInViewport(parent.current)) {
autoAnimate(parent.current);
}
}, [parent]);Issue #13: Deleted Elements Overlay Existing Content
问题#13:已删除元素覆盖现有内容
Error: Removed items overlay other items during fade out
Source: https://github.com/formkit/auto-animate/issues/231
Why It Happens: Exit animation maintains z-index, covering active content
Prevention: Add explicit z-index handling
tsx
// CSS workaround
<style>{`
[data-auto-animate-target] {
z-index: -1 !important;
}
`}</style>错误表现:移除的元素在淡出过程中覆盖其他元素
来源:https://github.com/formkit/auto-animate/issues/231
问题原因:退出动画会保持z-index,覆盖活跃内容
解决方法:添加显式z-index处理
tsx
// CSS 解决方案
<style>{`
[data-auto-animate-target] {
z-index: -1 !important;
}
`}</style>Issue #14: Cannot Disable During Drag & Drop
问题#14:拖拽过程中无法禁用动画
Error: Calling enable(false) doesn't prevent animations during drag
Source: https://github.com/formkit/auto-animate/issues/215
Why It Happens: Disable doesn't work reliably mid-drag
Prevention: Conditionally remove ref during drag
tsx
const [isDragging, setIsDragging] = useState(false);
const [parent] = useAutoAnimate();
return (
<ul ref={isDragging ? null : parent}>
{/* items */}
</ul>
);错误表现:调用enable(false)无法阻止拖拽时的动画
来源:https://github.com/formkit/auto-animate/issues/215
问题原因:拖拽过程中禁用功能不可靠
解决方法:拖拽期间条件性移除ref
tsx
const [isDragging, setIsDragging] = useState(false);
const [parent] = useAutoAnimate();
return (
<ul ref={isDragging ? null : parent}>
{/* 列表项 */}
</ul>
);Issue #15: CSS Transform Parent Position Bug
问题#15:CSS变换父元素位置漏洞
Error: Items animate from wrong position after parent transform
Source: https://github.com/formkit/auto-animate/issues/227
Why It Happens: Items remember original position before transform
Prevention: Delay autoAnimate until transform completes
tsx
useEffect(() => {
if (showList && parent.current) {
setTimeout(() => {
autoAnimate(parent.current);
}, 300); // Match CSS transition duration
}
}, [showList]);错误表现:父元素变换后,元素从错误位置开始动画
来源:https://github.com/formkit/auto-animate/issues/227
问题原因:元素会记住变换前的原始位置
解决方法:延迟autoAnimate直到变换完成
tsx
useEffect(() => {
if (showList && parent.current) {
setTimeout(() => {
autoAnimate(parent.current);
}, 300); // 匹配CSS过渡时长
}
}, [showList]);Critical Rules (Error Prevention)
关键规则(错误预防)
Always Do
必须遵循
✅ Use unique, stable keys - not
✅ Keep parent in DOM - Parent ref element always rendered
✅ Client-only for SSR - Dynamic import for server environments
✅ Respect accessibility - Keep
✅ Test with motion disabled - Verify UI works without animations
✅ Use explicit width - Avoid flex-grow on animated elements
✅ Apply to tbody for tables - Not individual rows
key={item.id}key={index}disrespectUserMotionPreference: false✅ 使用唯一且稳定的Key - 而非
✅ 保持父元素在DOM中 - 父元素ref始终渲染
✅ SSR环境下仅客户端使用 - 服务器环境使用动态导入
✅ 尊重无障碍设计 - 保持
✅ 测试禁用动画的情况 - 验证无动画时UI正常工作
✅ 使用明确宽度 - 避免为动画元素设置flex-grow
✅ 为表格的tbody应用动画 - 而非单独行
key={item.id}key={index}disrespectUserMotionPreference: falseNever Do
禁止操作
❌ Conditional parent -
❌ Index as key - breaks animations
❌ Ignore SSR - Will break in Cloudflare Workers/Next.js
❌ Force animations - breaks accessibility
❌ Animate tables directly - Use tbody or div-based layout
❌ Skip unique keys - Required for proper animation
❌ Complex animations - Use Motion instead
{show && <ul ref={parent}>}key={index}disrespectUserMotionPreference: trueNote: AutoAnimate respects automatically (never disable this).
prefers-reduced-motion❌ 条件渲染父元素 -
❌ 使用索引作为Key - 会破坏动画
❌ 忽略SSR问题 - 会导致Cloudflare Workers/Next.js中失效
❌ 强制启用动画 - 违反无障碍设计
❌ 直接为表格应用动画 - 使用tbody或基于div的布局
❌ 跳过唯一Key - 动画正常工作的必要条件
❌ 复杂动画场景 - 改用Motion库
{show && <ul ref={parent}>}key={index}disrespectUserMotionPreference: true注意:AutoAnimate会自动尊重设置(切勿禁用此功能)。
prefers-reduced-motionCommunity Tips (Community-Sourced)
社区技巧(社区贡献)
Note: These tips come from community discussions. Verify against your version.
说明:这些技巧来自社区讨论,请根据你的版本验证有效性。
Tip: Prevent Test Freezing with Mocked Package
技巧:通过模拟包避免测试冻结
Source: Issue #230 | Confidence: MEDIUM
Applies to: v0.8.2+
Tests may freeze for ~10 seconds when package is mocked. Add ResizeObserver mock:
typescript
// jest.setup.js
global.ResizeObserver = jest.fn().mockImplementation(() => ({
observe: jest.fn(),
unobserve: jest.fn(),
disconnect: jest.fn(),
}));
// __mocks__/@formkit/auto-animate.js
const autoAnimate = jest.fn(() => () => {});
const useAutoAnimate = jest.fn(() => [null, jest.fn(), jest.fn()]);
module.exports = { default: autoAnimate, useAutoAnimate };来源:Issue #230 | 可信度:中等
适用版本:v0.8.2+
模拟包时测试可能冻结约10秒。添加ResizeObserver模拟:
typescript
// jest.setup.js
global.ResizeObserver = jest.fn().mockImplementation(() => ({
observe: jest.fn(),
unobserve: jest.fn(),
disconnect: jest.fn(),
}));
// __mocks__/@formkit/auto-animate.js
const autoAnimate = jest.fn(() => () => {});
const useAutoAnimate = jest.fn(() => [null, jest.fn(), jest.fn()]);
module.exports = { default: autoAnimate, useAutoAnimate };Tip: Memory Leak Prevention
技巧:内存泄漏预防
Source: Issue #180 | Confidence: LOW
Applies to: All versions
For long-lived SPAs, ensure proper cleanup:
tsx
useEffect(() => {
const cleanup = autoAnimate(parent.current);
return () => cleanup && cleanup();
}, []);
// useAutoAnimate hook handles cleanup automatically
const [parent] = useAutoAnimate(); // Preferred来源:Issue #180 | 可信度:低
适用版本:所有版本
对于长期运行的SPA,确保正确清理:
tsx
useEffect(() => {
const cleanup = autoAnimate(parent.current);
return () => cleanup && cleanup();
}, []);
// useAutoAnimate钩子会自动处理清理
const [parent] = useAutoAnimate(); // 推荐写法Package Versions
包版本
Latest: @formkit/auto-animate@0.9.0 (Sept 5, 2025)
Recent Releases:
- v0.9.0 (Sept 5, 2025) - Current stable
- v0.8.2 (April 10, 2024) - Fixed Nuxt 3 ESM imports, ResizeObserver guard
json
{
"dependencies": {
"@formkit/auto-animate": "^0.9.0"
}
}Framework Compatibility: React 18+, Vue 3+, Solid, Svelte, Preact
Important: For Nuxt 3 users, v0.8.2+ is required. Earlier versions have ESM import issues
最新版本:@formkit/auto-animate@0.9.0(2025年9月5日)
近期发布:
- v0.9.0(2025年9月5日) - 当前稳定版
- v0.8.2(2024年4月10日) - 修复Nuxt 3 ESM导入问题,添加ResizeObserver防护
json
{
"dependencies": {
"@formkit/auto-animate": "^0.9.0"
}
}框架兼容性:React 18+、Vue 3+、Solid、Svelte、Preact
重要提示:Nuxt 3用户需要使用v0.8.2+版本。早期版本存在ESM导入问题
Official Documentation
官方文档
- Official Site: https://auto-animate.formkit.com
- GitHub: https://github.com/formkit/auto-animate
- npm: https://www.npmjs.com/package/@formkit/auto-animate
- React Docs: https://auto-animate.formkit.com/react
Templates & References
模板与参考资源
See bundled resources:
- - Copy-paste examples (SSR-safe, accordion, toast, forms)
templates/ - - CSS conflicts, SSR patterns, library comparisons
references/
查看捆绑资源:
- - 可复制粘贴的示例(SSR安全、手风琴、提示框、表单)
templates/ - - CSS冲突、SSR模式、库对比
references/