Communitygithub.com

Frontend Animation

Design, implement, review, and optimize frontend animations. Use this skill when the user asks for animations, transitions, scroll effects, hover feedback, loading animations, particles, 3D effects, parallax, skeleton screen transitions, number scrolling, or mentions Framer Motion, motion, GSAP, ScrollTrigger, Three.js, React Three Fiber, Lottie, View Transitions, Web Animations API, CSS transition/animation, spring, easing, etc.

What is Frontend Animation?

This Frontend Animation skill empowers AI agents to design, implement, review, and optimize frontend animations with a strong emphasis on best practices, performance, and accessibility. It provides a comprehensive decision-making framework, starting with dependency and design system detection, followed by a strict anti-pattern checklist to avoid common pitfalls like using `transition: all` or excessive elements animating simultaneously. The skill enforces precise numeric specifications for durations, easing curves, and amplitudes, all derived from UX research and performance constraints, and mandates using predefined tokens rather than hardcoded values. It covers a wide range of animation scenarios—from simple hover effects and page transitions to complex timelines, 3D with Three.js, and Lottie vector animations—while prioritizing CSS transitions for simple interactions and reserving heavier libraries like GSAP for complex scroll-driven sequences. Built-in review and self-check modes ensure animations meet accessibility requirements (including `prefers-reduced-motion`), performance budgets, and design intent before any code is committed. The skill supports React, Next.js, Vue, and pure CSS projects, adapting its recommendations to the existing tech stack without imposing unnecessary dependencies.

Works with✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/HEI1491/frontend-animation-skill/tree/HEAD

Ask in your favorite AI

Open a new chat with this agent skill pre-loaded.

Documentation

What does Frontend Animation do?

You are responsible for designing, implementing, reviewing, and optimizing frontend animations. By default, assume the project is React + TypeScript; for pure JS or other frameworks, follow the project's current setup—do not force React solutions on Vue or vanilla projects.

Animation is enhancement, not decoration: first ensure the static version looks good and is usable, then add animation.

Do not add any new dependencies without user confirmation.

§0 Prerequisites: Dependency & Design System Detection

Before starting, complete the following five steps in order; if any step is missing, detect it first before writing code.

  1. Read package.json and the actual locked versions in pnpm-lock.yaml / package-lock.json / yarn.lock to confirm installed animation libraries and their major versions.
  2. Read tailwind.config.*, global styles (globals.css / index.css / app.css), and theme files to identify existing tokens, durations, easings, and naming conventions.
  3. If motion exists, do not use GSAP; if GSAP exists, do not add motion. Never have two animation libraries for the same need.
  4. Do not add new dependencies without permission. If a new dependency is truly needed, first explain the package name, min+gzip size, alternatives, and why the existing library cannot do it, then wait for user confirmation before installing.
  5. Follow the project's existing naming, file organization, code style, and token names—do not introduce a second animation system.
DetectedDefault approach
Existing motionUse motion for interactions, enter/exit, and layout animations; do not introduce GSAP
Existing framer-motion (older version)Keep the existing package name and API; do not migrate to motion without explicit request; upgrade separately
Existing GSAPUse GSAP + ScrollTrigger for timelines and scroll-linked animations; use CSS transitions for simple hovers—do not add motion
Only TailwindUse transition / duration / ease utility classes with global CSS variables; do not install a library
Pure CSS projectUse only CSS transitions/animations + WAAPI; do not install JS animation libraries
Next.js App RouterMark animation components with "use client". Handle View Transitions and motion as client components; do not use cross-route shared state hacks
VueUse native CSS or Vue ecosystem motion solutions; do not force React-specific libraries into the project

§1 Anti-Pattern Checklist (Do Not Violate)

Check each item. If any is violated, revert and rewrite—no "just this once" compromises.

ForbiddenAlternative
transition: all .3sExplicitly list transform, opacity, and add color if needed
Global ease-in-out for everythingChoose curves based on context: enter / exit / bidirectional (see §3)
Element popping in from opacity: 0 + scale(.8)Use opacity: .9→1 + translateY(8px)→0
Blind use of linearOnly for progress bars and infinite loop decorations
More than 3 elements animating simultaneously on the same screenKeep only 1 visual focus; others remain static or very subtle
Hover with transform: translateY(-4px) but parent container has no reserved spaceUse scale or add padding to the parent
Only implement enter animation, no exitMust design enter and exit in pairs, with exit faster than enter
Large-area filter: blur() / drop-shadow animationUse pre-rendered blurred layers, or reduce the animation scope
Animation layer covering CTA / formsSet pointer-events: none on the animation layer, or keep it away from interactive areas
Page splash screen loading animation exceeding 1.5sIf it exceeds, show a skeleton screen first
Custom cursor + trailing effect (unless explicitly requested by user)Do not do it
Complex per-word or per-frame animation on every list itemUse a 30–50ms stagger with a collective translate
Chaining animations with setTimeoutUse transition/animation events, onAnimationComplete, or a timeline
Per-frame el.style.left = xUse WAAPI / rAF / library timeline

Rationale for thresholds: When the first screen wait exceeds 1.5s, users start to suspect the page is frozen, so show a skeleton screen first. When more than 3 independent motions occur on the same screen, visual focus is lost and users don't know where to look.

§2 Decision Tree (Abbreviated)

First, determine the approach using the table below, then go to §3 to set values, and only then write code.

ScenarioFirst choiceShould not use
Hover / press / toggle feedbackCSS transitionGSAP (too heavy)
Component enter/exit, list add/remove, layout changesmotion (AnimatePresence + layout)Manual height animation
Route/page transitionsView Transitions API, or motion layoutIdFull-screen overlay + delay
Complex timelines, sequence orchestration, scroll-linked animationsGSAP + ScrollTriggerCSS keyframes pile-up
3D / particles / physics / shadersthree.js + React Three Fiber + dreiFaking 3D with CSS
Designer-provided vector animationsdotLottie / LottieConvert to GIF
Simple icons or path animationsSVG + CSSIntroducing Lottie runtime
Data chart animationsLibrary's built-in animation (e.g., Recharts/visx transitions)Hand-tweening paths
Background decorations (grids/waves/glows)CSS or canvas + requestAnimationFrame, and pause-ablethree.js (unless you really need 3D)
Number/amount changestabular-nums + simple tweenPer-frame layout reflow

For full decision logic, question ordering, and the "CSS → light library → heavy library" upgrade ladder, see references/decision-tree.md.

§3 Value Specifications (No Guesswork Allowed)

All durations, curves, and amplitudes must be taken from the following tables. If a value is not listed, first justify it before adding it.

Duration

ItemValue
Hover / press120–180ms
Toggle / expand-collapse200–300ms
Enter240–400ms
Exit60–70% of enter duration
Page transition300–500ms
Layout reorder (layout animation)300–500ms
Stagger interval30–50ms, total group duration ≤ 500ms
Over 600msMust justify reason, otherwise cut it

Easing

EasingCurve
Entercubic-bezier(0.16, 1, 0.3, 1)
Exitcubic-bezier(0.4, 0, 1, 1)
Bidirectional / state togglecubic-bezier(0.4, 0, 0.2, 1)
Translation / drag / gesturespring: stiffness 300–500, damping 30–40
LinearOnly for progress bars, infinite loop decorations

Amplitude

AmplitudeValue
TranslationMicro 4–8px / Medium 12–24px / Large 32–64px / >80px only for full-screen transitions
OpacityMicro-interaction .9→1; Enter .6→1; 0→1 only for full-screen overlays and modals
ScaleOnly within 0.96–1.04 range

Spring

ParameterValueRationale
stiffness300–500Below 300 is sluggish; above 500 shakes like a fault
damping30–40Below 30 overshoots too much; above 40 feels no bounce
mass0.8–1Minimal change to make inertia perceptible

Rationale for each interval, one sentence each:

  • Hover / press 120–180ms: Below 120ms the state change is imperceptible; above 180ms feedback is laggy, and users feel they missed the target.
  • Enter 240–400ms: Below 240ms the movement direction is unreadable; above 400ms users start waiting.
  • Exit × 0.65: Departures don't need to be clearly seen; slow means sluggish.
  • Stagger 30–50ms: Below 30ms it looks like everything appears together; above 50ms the group exceeds the 500ms patience threshold.

These values have been encoded as CSS variables and TypeScript constants; see references/tokens.md. All code must reference tokens—hardcoded numbers are forbidden.

§4 Performance & Accessibility Red Lines

  1. Only animate transform / opacity. To animate dimensions, use FLIP or the library's layout capability.
  2. For layers that will be continuously animating, add will-change: transform and remove it after the animation ends.
  3. Virtualize long lists; use IntersectionObserver to pause animations on off-screen elements.
  4. prefers-reduced-motion: reduce is a mandatory branch, not a nice-to-have. The fallback must still show clear state changes: typically degrade to opacity crossfade ≤120ms (120ms is enough to read the state switch without requiring understanding of animation), or direct switch.
  5. Do not use flashing more than 3 times per second (WCAG 2.3.1 photosensitivity threshold is 3 flashes per second).
  6. Do not steal focus or disturb tab order during animation; keyboard focus rings should not participate in animation.
  7. Design with the principle that "the static version should also look good"; animation is only an enhancement.

For WCAG guidelines, aria-live, and testing methods, see references/accessibility.md.

§5 Implementation Laws

  • Design enter and exit in pairs, with exit faster.
  • Keep only one visual focus per screen.
  • Use 30–50ms stagger, total group ≤ 500ms.
  • Decorative animations must have pointer-events: none.
  • Chain animations using transition/animation events, onAnimationComplete, or a timeline—never setTimeout.
  • If CSS or Framer can do it, don't use GSAP.
  • If transform works, don't animate width / height.
  • Submit animation duration to design review; don't adjust by "feeling slow".
  • Subtract first, then add: remove animations you can, then optimize the ones you can't.

§6 Review Mode

When reviewing existing animations, output each issue in the following fixed four-part format:

Problem / Evidence (cite clauses from §1–§4) / Suggested code / Impact (duration, performance, accessibility)

Rules:

  • Report only real problems. Don't rewrite reasonable implementations just to fill space.
  • Maximum 8 items, sorted by severity: accessibility > performance > duration/curve > style.
  • End with a "These are correct" section listing 1–3 items to prevent the user from mistakenly changing good implementations.

Scan command (read-only, no --fix; any automatic change to animations would break design intent):

node ~/.claude/skills/frontend-animation/scripts/audit-animation.mjs <project-directory> --json

The script only reports problems and locations; fixes are decided by humans.

§7 What to Read When You Need X

Symptom / NeedFile
Unsure whether to use CSS or a library, need to choose between frameworks, need to ask questions in orderreferences/decision-tree.md
Need to apply tokens, integrate with Tailwind, write CSS variables or TS constantsreferences/tokens.md
Look up installation, API, version pitfalls for motion / GSAP / three.js+R3F / Lottie / View Transitionsreferences/libraries.md
Need ready-made templates (list enter / route transition / drag / mouse-follow / number scroll / 3D flip / cyclic background / skeleton screen / magnetic button / Lottie)references/patterns.md
Choose easing curves, need linear() approximation for spring, explain why a certain curve is usedreferences/easing.md
reduced-motion fallback, WCAG, flashing and focus, testing methodsreferences/accessibility.md
Need a reference component with full reduced-motion branchassets/template-component.tsx
Need to scan existing code for animation issuesscripts/audit-animation.mjs

§8 Self-Check Before Commit (8 Questions, Answer Each)

  1. Is this animation necessary? Does the static version still look good without it?
  2. Are we only animating transform / opacity?
  3. Are duration, curve, and amplitude all within §3?
  4. Are enter and exit designed as a pair, with exit faster?
  5. Is there a reduced-motion branch, and can the state still be discerned after degradation?
  6. Have we added any new dependencies? Doing so without confirmation is a violation.
  7. Is there any flashing >3 times/second, or focus stealing during animation?
  8. Is there only one visual focus on the screen?

If any question cannot be answered, stop and fix it—do not commit.

Related Skills