auto-animate

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

AutoAnimate - 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.tsx

Issue #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:
flex-grow: 1
waits for surrounding content, causing timing issues Prevention: Use explicit width instead of flex-grow for animated elements
tsx
// ❌ 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: 1
会等待周围内容加载,导致时序问题 解决方法:为动画元素使用明确宽度而非flex-grow
tsx
// ❌ 错误写法 - 导致抖动
<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
<tbody>
instead of individual rows, or use div-based layouts
错误表现:移除行时表格结构破坏 来源https://github.com/formkit/auto-animate/issues/7 问题原因:Display: table-row与动画冲突 解决方法:将动画应用于
<tbody>
而非单独行,或使用基于div的布局

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
moduleNameMapper
in jest.config.js
错误信息:"Cannot find module '@formkit/auto-animate/react'" 来源https://github.com/formkit/auto-animate/issues/29 问题原因:Jest无法正确解析ESM导出 解决方法:在jest.config.js中配置
moduleNameMapper

Issue #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
position: relative
Prevention: Account for position change in CSS or set explicitly
错误表现:添加AutoAnimate后布局破坏 来源:官方文档 问题原因:父元素会自动设置
position: relative
解决方法:在CSS中考虑定位变化或显式设置定位

Issue #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 -
key={item.id}
not
key={index}
Keep parent in DOM - Parent ref element always rendered ✅ Client-only for SSR - Dynamic import for server environments ✅ Respect accessibility - Keep
disrespectUserMotionPreference: false
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 -
key={item.id}
而非
key={index}
保持父元素在DOM中 - 父元素ref始终渲染 ✅ SSR环境下仅客户端使用 - 服务器环境使用动态导入 ✅ 尊重无障碍设计 - 保持
disrespectUserMotionPreference: false
测试禁用动画的情况 - 验证无动画时UI正常工作 ✅ 使用明确宽度 - 避免为动画元素设置flex-grow ✅ 为表格的tbody应用动画 - 而非单独行

Never Do

禁止操作

Conditional parent -
{show && <ul ref={parent}>}
Index as key -
key={index}
breaks animations ❌ Ignore SSR - Will break in Cloudflare Workers/Next.js ❌ Force animations -
disrespectUserMotionPreference: true
breaks accessibility ❌ Animate tables directly - Use tbody or div-based layout ❌ Skip unique keys - Required for proper animation ❌ Complex animations - Use Motion instead
Note: AutoAnimate respects
prefers-reduced-motion
automatically (never disable this).

条件渲染父元素 -
{show && <ul ref={parent}>}
使用索引作为Key -
key={index}
会破坏动画 ❌ 忽略SSR问题 - 会导致Cloudflare Workers/Next.js中失效 ❌ 强制启用动画 -
disrespectUserMotionPreference: true
违反无障碍设计 ❌ 直接为表格应用动画 - 使用tbody或基于div的布局 ❌ 跳过唯一Key - 动画正常工作的必要条件 ❌ 复杂动画场景 - 改用Motion库
注意:AutoAnimate会自动尊重
prefers-reduced-motion
设置(切勿禁用此功能)。

Community 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

官方文档

Templates & References

模板与参考资源

See bundled resources:
  • templates/
    - Copy-paste examples (SSR-safe, accordion, toast, forms)
  • references/
    - CSS conflicts, SSR patterns, library comparisons
查看捆绑资源:
  • templates/
    - 可复制粘贴的示例(SSR安全、手风琴、提示框、表单)
  • references/
    - CSS冲突、SSR模式、库对比