CSS Animation Generator

CSS animations are how you bring interfaces to life — but writing @keyframes by hand is tedious and the shorthand animation property has eight values that always confuse. This generator gives you a visual editor with the most common animation presets (fade, slide, scale, rotate, bounce, pulse) and full control over duration, delay, easing, iterations, direction, and fill mode. Hit Replay to see exactly how your animation will run, then copy the production-ready CSS.

Preview

What is CSS animation?

The CSS animation shorthand property combines up to eight individual properties into a single declaration: animation-name, animation-duration, animation-timing-function, animation-delay, animation-iteration-count, animation-direction, animation-fill-mode, and animation-play-state. You define the motion itself inside an @keyframes rule — a set of named steps that describe how properties change over time — and then reference that name in the animation shorthand along with the timing values that control how the keyframes play out.

CSS animations are fundamentally different from CSS transitions. Transitions require a trigger (a hover, focus, or class change) and only interpolate between two states. Animations run automatically as soon as the animation property is applied and can define any number of intermediate steps. This makes them ideal for loading indicators, entrance effects, attention-grabbing pulses, and any motion that needs to run independently of user interaction. You can loop animations infinitely, alternate their direction, add delays, and control what happens before and after playback with fill modes.

The @keyframes rule is the heart of every CSS animation. It uses percentage-based steps (or the keywords from and to for 0% and 100%) to define property values at specific points in the animation timeline. The browser interpolates between these keyframe values according to the easing function you specify. You can animate nearly any CSS property that has a computable intermediate value — transforms, opacity, colors, dimensions, spacing, and more. Properties that cannot be interpolated (like display) will switch at the midpoint of the specified duration.

How to use this tool

Start by choosing a preset from the dropdown — each preset loads a different @keyframes rule optimized for a common use case. Adjust the duration and delay sliders to control timing, pick an easing curve, and set the iteration count (or check "Infinite" for a looping animation). Choose a direction and fill mode, then click "Replay" to preview the result on the demo box. Once you are happy with the animation, copy the direct CSS or CSS variable version using the copy buttons below the preview.

Each setting in the tool corresponds directly to a CSS animation sub-property. The duration slider controls animation-duration. The delay slider sets animation-delay. The easing dropdown maps to animation-timing-function. The iteration count corresponds to animation-iteration-count. The direction dropdown controls animation-direction (normal, reverse, alternate, or alternate-reverse). And the fill mode dropdown controls animation-fill-mode, which determines whether the element retains the animation's start or end state outside of its active playback period.

Practical examples

Loading spinner with rotate animation

A classic loading spinner uses a continuous rotation animation. The element is styled as a partial circle using borders, and the rotate keyframes spin it 360 degrees infinitely with a linear timing function for smooth, constant-speed rotation.

.spinner {
  width: 40px;
  height: 40px;
  border: 4px solid #1e293b;
  border-top-color: #7c9eff;
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
}

@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}

Fade-in and slide-up entrance animation

Entrance animations combine opacity and transform changes to make elements appear smoothly. This pattern is widely used for page sections, card grids, and modal dialogs. The forwards fill mode ensures the element stays visible after the animation completes.

.fade-in-up {
  opacity: 0;
  animation: fadeInUp 0.6s ease-out forwards;
}

@keyframes fadeInUp {
  from {
    opacity: 0;
    transform: translateY(20px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* Staggered entrance for multiple items */
.fade-in-up:nth-child(2) { animation-delay: 0.1s; }
.fade-in-up:nth-child(3) { animation-delay: 0.2s; }
.fade-in-up:nth-child(4) { animation-delay: 0.3s; }

Pulse/heartbeat attention effect

A pulse animation draws the user's eye to an important element, such as a notification badge or a call-to-action button. The scale transform grows and shrinks the element rhythmically, and the alternate direction creates a seamless back-and-forth motion.

.pulse {
  animation: pulse 1.5s ease-in-out infinite;
}

@keyframes pulse {
  0% {
    transform: scale(1);
    opacity: 1;
  }
  50% {
    transform: scale(1.05);
    opacity: 0.85;
  }
  100% {
    transform: scale(1);
    opacity: 1;
  }
}

/* Notification badge pulse */
.badge-pulse {
  animation: badgePulse 2s ease-in-out infinite;
}

@keyframes badgePulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(124, 158, 255, 0.5); }
  50% { box-shadow: 0 0 0 10px rgba(124, 158, 255, 0); }
}

Shake animation for form validation errors

A horizontal shake draws attention to an invalid form field without being as intrusive as a color flash. The animation uses small translateX values to create a rapid side-to-side motion that naturally settles back to the element's original position.

.shake {
  animation: shake 0.4s ease-in-out;
}

@keyframes shake {
  0%, 100% { transform: translateX(0); }
  10%, 50%, 90% { transform: translateX(-4px); }
  30%, 70% { transform: translateX(4px); }
}

/* Apply on invalid form submission */
.input-error {
  animation: shake 0.4s ease-in-out;
  border-color: #f87171;
  outline-color: #f87171;
}

Common patterns and best practices

Writing effective CSS animations requires attention to performance, accessibility, and user experience:

Browser support

CSS animations and @keyframes are supported in all modern browsers including Chrome, Firefox, Safari, and Edge. The feature has been stable since the early 2010s and no longer requires vendor prefixes in any current browser. The -webkit-animation prefix is obsolete and should not be used in new code.

Modern additions to CSS animations, such as the animation-timeline property for scroll-driven animations, have more limited support and are separate from the core animation features covered by this tool. The core animation shorthand, @keyframes, and all eight sub-properties (animation-name, animation-duration, animation-timing-function, animation-delay, animation-iteration-count, animation-direction, animation-fill-mode, animation-play-state) are universally available and safe for production use.

FAQ

What's the difference between animation and transition?

CSS transitions require a state change to trigger — such as a hover, focus, or class toggle — and they only animate between a start and end state. CSS animations, on the other hand, run automatically when applied and can define multiple intermediate steps via @keyframes. Animations also support looping, alternating directions, and delays without needing any JavaScript or user interaction to fire.

Why is my animation not running?

The most common causes are: the animation-fill-mode is set to none, which means the element snaps back to its original state instantly after the animation ends — change it to forwards to keep the final frame. Also check that animation-iteration-count is at least 1, that the element is visible (not display: none), and that the @keyframes name in your animation shorthand matches the name in your @keyframes rule exactly, including casing.

How do I pause and resume a CSS animation?

Use animation-play-state: paused to pause and animation-play-state: running to resume. This can be toggled with a class change or :hover pseudo-class, and the animation continues from exactly where it paused — it does not restart from the beginning. For example, you could pause a background animation when the user hovers over it, or pause all animations when a modal is open by toggling a class on a parent element.

What is animation-fill-mode and why does my element snap back?

animation-fill-mode: forwards keeps the element in its final keyframe state after the animation ends. Without it (or with none), the element reverts to its original styles as soon as the animation completes, causing a visible snap-back effect. If you also have a delay, use animation-fill-mode: both — this applies the first keyframe's styles during the delay period (backwards) and keeps the last keyframe's styles after completion (forwards). This eliminates visual jumps at both the start and end of the animation.

Should I use CSS animations or the Web Animations API?

CSS animations are simpler for declarative, state-driven animations such as hover effects, entrance animations, and loading indicators. They are defined entirely in CSS, require no JavaScript, and are easy to maintain. The Web Animations API provides programmatic control — dynamic timing adjustments, playback rate changes, promises for completion callbacks, and the ability to create animations on the fly. Use CSS animations for predictable, design-driven motion. Use the Web Animations API when you need runtime control, such as interactive drag-to-animate effects, game animations, or dynamically generated animation sequences.

How do I make animations respect prefers-reduced-motion?

Wrap your animation styles in @media (prefers-reduced-motion: no-preference) { ... } so they only apply when the user has not requested reduced motion. Alternatively, add a @media (prefers-reduced-motion: reduce) block that sets animation: none or animation-duration: 0.01ms on animated elements. This respects users who have enabled reduced motion in their OS settings due to vestibular disorders or motion sensitivity. It is considered a best practice and an accessibility requirement for production websites.

Related tools