CSS Animation Generator
0.6s
0s
Preview
.element {
  animation: fade-in 0.6s ease 0s 1 normal forwards;
}

@keyframes fade-in {
  from { opacity: 0; }
  to { opacity: 1; }
}
🔖
Bookmark this page
Press Ctrl+D to save this tool in your browser for instant access anytime — no sign-up needed.

CSS Keyframe Animation Generator — 19 Animation Effects

Share

About this tool

Pick a CSS Animation, Adjust the Settings, Copy the @keyframes Code

You need a fadeIn for a modal, a bounce for a notification badge, or a spin for a loading indicator — but writing @keyframes by hand and tweaking the timing, easing, and fill-mode in DevTools is slow. Pick one of 19 presets here, adjust the settings, see it live, and copy the complete CSS block in one click.

Every animation exposes the full set of CSS animation properties: duration, delay, easing (ease, linear, ease-in/out, or custom cubic-bezier), fill-mode (none, forwards, backwards, both), direction (normal, reverse, alternate), and iteration count (any number or infinite). The live preview replays whenever you change any setting — click Replay to restart it manually. Set fill-mode to forwards for entrance animations that should stay in their end state. Set iterations to infinite for loaders and ambient effects.

19 presets cover the most common motion patterns: fade (in/out), slide (4 directions), bounce, spin, pulse, shake, flip, zoom (in/out), swing, heartbeat, wobble, flash, rubberBand, and jackInTheBox. Export as raw CSS with the @keyframes block and animation property, Tailwind arbitrary value syntax, or a React JSX snippet with the keyframes embedded in a style tag.

Features

  • 19 CSS keyframe animation presets — fade, bounce, spin, shake, flip, zoom, pulse, and more
  • Duration and delay controls in seconds with decimal precision
  • Easing selector — ease, linear, ease-in/out, ease-in-out, custom cubic-bezier
  • Animation fill-mode selector — none, forwards, backwards, both
  • Direction selector — normal, reverse, alternate, alternate-reverse
  • Iteration count — any number or "infinite" for continuous loops
  • Live animated preview with Replay button
  • Auto-generated scoped class name to avoid conflicts in real projects
  • Export as CSS @keyframes + animation property, Tailwind arbitrary value, or React snippet
  • 100% client-side — no data sent to any server

How to Use

Choose one of the 19 animation presets from the list on the left side of the tool — click any preset name to load it immediately and see the animation play in the preview box. The preview box replays the animation each time you change any setting; click the Replay button manually to restart it at any time. In the controls panel on the right, set the Duration in seconds to control how long the animation takes to complete one cycle. Set the Delay in seconds if you want the animation to wait before starting — useful for staggered sequences where multiple elements animate one after another. Choose an Easing function from the dropdown: ease, linear, ease-in, ease-out, ease-in-out, or a custom cubic-bezier value for advanced curves. Set Fill Mode to control the element's style before and after the animation plays — "forwards" is the most common choice for entrance animations. Set Direction to "normal", "reverse", "alternate", or "alternate-reverse" to control whether each iteration plays forward, backward, or alternates. Set Iterations to a number or "infinite" for looping. Switch between the CSS, Tailwind, and React export tabs at the bottom and click Copy to copy the output to your clipboard, or Download to save it as a file.

Common Use Cases

Animate a modal, toast, or dropdown entrance
Pick slideInUp or fadeIn, set duration to 0.2–0.3s, fill-mode to forwards. The element appears smoothly rather than snapping in abruptly. Copy the CSS and apply the class when the element mounts.
Reveal elements as the user scrolls
Generate the CSS for a fadeIn or slideInUp with fill-mode: forwards — so elements stay visible after the animation ends. Trigger the class via IntersectionObserver or a CSS scroll-driven animation when the element enters the viewport.
Create a loading spinner or skeleton shimmer
Use spin or pulse with animation-iteration-count: infinite. Duration of 0.8–1.2s creates a natural loading rhythm. Copy the CSS and apply it to any spinner icon or skeleton element.
Draw attention to an error state or notification badge
Shake works for form validation errors. Flash or heartbeat works for badges and alerts. Set iterations to 2–3 rather than infinite — enough to catch attention without being annoying.
Add personality to empty states or landing page illustrations
Apply bounce or swing to an SVG icon with direction: alternate and iteration: infinite for a natural back-and-forth oscillation. The alternate direction avoids the jarring jump of a standard looping animation.
Get a Tailwind animation class or React snippet without writing @keyframes
The Tailwind tab generates the animation as an arbitrary value class for direct use in className. The React tab generates a complete JSX snippet with the @keyframes block embedded in a style tag — paste into any component.

Frequently Asked Questions

Pick an animation preset, adjust the duration, easing, fill-mode, direction, and iterations, then copy the CSS tab output. It includes the @keyframes block and the animation property — paste both into your stylesheet and apply the generated class name to any element. No JavaScript required.

"forwards" is the most common value — it holds the final keyframe state after the animation ends, so an entrance animation like fadeIn leaves the element visible. "none" (default) snaps back to the original style when done, which causes entrance animations to disappear immediately. "backwards" applies the first keyframe state during the delay period. "both" combines forwards and backwards.

Set the iteration count to "infinite" in the Iterations control. The exported CSS uses animation-iteration-count: infinite. Use direction: alternate for effects like pulse or bounce to create a back-and-forth oscillation rather than a jarring loop restart.

Generate the animation CSS with fill-mode: forwards so the element stays in its end state after the animation completes. Initially set the element's visibility: hidden or opacity: 0. Add the animation class via an IntersectionObserver callback when the element enters the viewport. The element will animate in and remain visible.

ease (default) starts and ends slowly with a fast middle. ease-in starts slowly and accelerates — feels like it's gaining momentum, good for exit animations. ease-out starts fast and decelerates — feels like it's settling in, good for entrance animations (elements feel like they slide into place). ease-in-out is slow at both ends.

Switch to the React tab. The output includes the @keyframes block inside a <style> JSX tag and the animation applied via a className with a scoped auto-generated name. Copy and paste into any React component.

Copy the generated CSS and apply the animation property only in the :hover selector of your element: .element:hover { animation: fadeIn 0.3s ease forwards; }. The animation triggers when the cursor enters the element. Set fill-mode to none so it resets when the cursor leaves.

animation-direction controls whether each cycle plays forward or backward. "normal" (default) plays forward every cycle. "reverse" plays backward every cycle. "alternate" plays forward on odd cycles and backward on even cycles — this creates a natural oscillation for effects like pulse, bounce, and swing without a jarring jump back to the start state. "alternate-reverse" starts in reverse. For looping ambient animations (a floating icon, a breathing glow, a bouncing badge), direction: alternate with iteration-count: infinite produces the most natural-looking result.

Staggered animations use different animation-delay values for each element. Generate the base animation CSS here, then apply it to each element with an increasing delay: the first gets delay: 0s, the second delay: 0.1s, the third delay: 0.2s, and so on. Use CSS custom properties to make this scalable: --i: 0, --i: 1, --i: 2 on each element, then animation-delay: calc(var(--i) * 0.1s). Set fill-mode: backwards so each element stays hidden during its delay period — otherwise all elements will briefly show at their final state before animating.

Easing controls how the animation progresses through its keyframes over time — it sets the acceleration curve. "ease" starts slow, speeds up, then slows down at the end — a natural feel for most UI motion. "linear" moves at a constant rate the entire time — good for spinners and continuous rotation. "ease-in" starts slow and accelerates — suitable for exit animations where elements leave the screen. "ease-out" starts fast and decelerates — best for entrance animations where elements arrive and settle. "ease-in-out" is slow at both ends — ideal for elements that move across the screen from one position to another. For custom curves, use cubic-bezier(x1, y1, x2, y2).

Switch to the Tailwind tab in the export panel. The output uses Tailwind's arbitrary value syntax for the animation property: className="[animation:fadeIn_0.5s_ease_forwards]". The @keyframes block still needs to be added to your global CSS — paste it into your globals.css or tailwind.css file. For animations you use frequently, add them to tailwind.config.js under theme.extend.keyframes and theme.extend.animation — then you can use the named class like animate-fadeIn instead of an arbitrary value.

Transitions are simpler and better for state changes triggered by interaction — hover, focus, active. They interpolate between two states (before and after) automatically when the property changes. Animations with @keyframes are better for sequences that run on load, scroll triggers, or need multiple steps between start and end — like a bounce that overshoots, a shake with multiple oscillations, or a multi-step entrance that fades in and slides up simultaneously. Transitions require a state change to trigger; animations can start automatically and repeat independently of user interaction.