Free CSS Animation Generator
Build CSS @keyframes animations visually · pick a preset or customise timing, transforms & easing. Copy production-ready code.
Presets
Settings
Preview
Generated CSS
How It Works
- Choose an animation preset: select from common animations, fade, slide, bounce, spin, pulse, shake, and more.
- Customize timing and behavior: adjust duration, delay, easing function, iteration count, and fill mode.
- Copy the CSS: the complete @keyframes definition and animation shorthand property are ready to paste into your stylesheet.
Why Use CSS Animation Generator?
CSS animations bring interfaces to life, drawing attention to key elements, providing feedback, and creating polished user experiences. Writing @keyframes rules by hand requires knowing the correct syntax, easing names, and property combinations. This generator provides curated animation presets with live previews and lets you tweak every parameter, outputting production-ready CSS without requiring JavaScript or animation libraries.
Features
- Animation presets: fade, slide, bounce, spin, pulse, shake, flip, zoom, and more, all with live previews.
- Custom keyframes editor: build your own keyframe animation from scratch with a visual interface.
- Timing control: set duration (ms/s), delay, easing (linear, ease, cubic-bezier), and iteration count.
- Animation fill modes: control forwards, backwards, both, and none fill behavior.
- No JavaScript required: all generated animations are pure CSS, no libraries or frameworks needed.
Frequently Asked Questions
What is the difference between animation and transition in CSS?
CSS transitions trigger on state changes (hover, focus, class toggle) and animate between two states. CSS animations use @keyframes to define multiple states and run independently of user interaction, they can loop, reverse, and run automatically.
What is animation-fill-mode and why does it matter?
animation-fill-mode controls whether the element retains the animation's styles before it starts (backwards), after it ends (forwards), or both. Without forwards, the element snaps back to its original style when the animation completes.
Are CSS animations performance-friendly?
Animations that use only transform and opacity are GPU-accelerated and very smooth. Avoid animating layout properties like width, height, margin, or top/left, these trigger layout recalculations and can cause jank. Stick to transform and opacity for 60 fps animations.
What CSS animations actually do
CSS animations interpolate one or more CSS properties between defined keyframes over time, producing visible motion or change without JavaScript. The model has two pieces: @keyframes rules define what an animation looks like at percentage-based steps (0% to 100%), and the animation shorthand property (or its longhand siblings animation-duration, animation-delay, animation-timing-function, animation-iteration-count, animation-fill-mode) tells the browser how to play that keyframes definition. The browser handles all interpolation, easing, and frame timing in C++, typically GPU-accelerated for transform and opacity changes.
Animations differ from CSS transitions in two ways. Transitions fire when an element's state changes (a hover, a class toggle, a focus event) and interpolate between exactly two values: the old and the new. Animations run independently of state, follow an arbitrary number of keyframe steps, can loop indefinitely, can play in reverse, and can be triggered, paused, and resumed via CSS or JavaScript. Transitions are the right tool for "snap from A to B over half a second"; animations are the right tool for "loop this attention-grabbing pulse forever" or "play this entry sequence once when the element appears."
For modern web design, CSS animations replace a huge amount of what used to require JavaScript libraries. Spinners, fade-ins, slide-ups, attention pulses, success checkmarks: all are now standard CSS patterns. The trade-off is expressiveness for complex sequences. CSS animations can do a lot but stop being convenient around 5 to 7 keyframe steps with synchronized property changes; for storyboarded animations, scroll-linked sequences, or anything dynamic that depends on JavaScript state, dedicated libraries (GSAP, Framer Motion, Web Animations API) remain the better choice.
How this tool works under the hood
When you choose a preset (e.g., "bounce" or "fade-in") the tool loads a predefined @keyframes string into the preview area and applies the animation property to the preview box. The keyframes are real CSS, not a custom format: what you see is what you get to copy. Sliders update animation timing values (duration, delay, iteration count) by editing the inline animation property in real time, so the preview reflects every change instantly without page reload.
Easing function selection uses the standard CSS timing-function values: linear (constant speed), ease (default, slow start and end), ease-in (slow start), ease-out (slow end), ease-in-out (slow start and end), or cubic-bezier(x1, y1, x2, y2) for custom curves. The visible animation curve is computed by the browser's native timing-function implementation; the preview is the actual browser-rendered output, not a JavaScript simulation.
The code box shows the full CSS you need to drop into a stylesheet: both the @keyframes block and the .your-class { animation: ... } declaration. Click "Copy CSS" and both are written to your clipboard as a single text block. No file is generated, no server processes anything, and the tool has no backend to call. The preview, the code generation, and the clipboard write all happen in JavaScript on your device. Refresh the page and your custom configuration is gone unless you copied it first.
Brief history of web animation
- Flash dominates web motion, 1996 to 2010. Adobe Flash (originally Macromedia) is the primary tool for web animation throughout the early 2000s. Vector-based, timeline-driven, with a custom plugin runtime. By 2010, Flash powers most banner ads, YouTube video player, and Newgrounds-era games. Then mobile devices kill it: iPhone never supported Flash, Android drops support in 2012, browsers deprecate the plugin by 2020.
- CSS Transitions in WebKit, 2007. Apple's WebKit engine ships
-webkit-transitionin 2007, the first commonly-deployed CSS animation primitive. Used heavily in early iPhone web apps. By 2009 the property is in the CSS spec process and ships unprefixed across browsers by 2014. - CSS Animations Module Level 1, 2009. WebKit adds
-webkit-animationand@-webkit-keyframesin March 2009 ahead of the W3C CSS Animations Module Level 1 draft (also 2009). Firefox follows in version 5 (2011), IE in version 10 (2012). The "no JavaScript needed for basic animations" era begins. - GSAP and JS animation libraries, 2008 onwards. jQuery's
.animate()method (2006) starts the JS animation library era; GreenSock Animation Platform (GSAP, launched 2008) becomes the gold standard for complex sequenced animation, timeline scrubbing, and performance. Used in Disney, Coca-Cola, and Awwwards-tier marketing sites. Continues to coexist with CSS animations: GSAP for sequenced complexity, CSS for declarative simplicity. - Web Animations API standardized, 2014 to 2018. The W3C Web Animations specification provides a JavaScript API that exposes CSS animations and adds programmatic control:
element.animate(keyframes, options). Chrome ships in version 36 (2014), Firefox in version 75 (2020), Safari in version 13.1 (2020). Bridges the gap between declarative CSS and full library-power JavaScript. - Scroll-driven animations land, 2023 to 2024. CSS Scroll-driven Animations module introduces
animation-timeline, letting CSS animations bind to scroll position instead of (or in addition to) time. Chrome 115 (July 2023) ships first; Safari and Firefox add support through 2024 and 2025. Unlocks parallax effects, scroll-progress indicators, and section reveal animations in pure CSS.
Real-world workflows
- Loading spinners and skeleton states. A spinning loader (
animation: spin 1s linear infinitewith a 360-degree rotation keyframe) is the most common CSS animation use. Skeleton screens with a sliding shimmer effect use a translateX or background-position animation. Both are essential for perceived performance: while content loads, the animation tells users "we're working on it" rather than "it's broken." - Hover and focus micro-interactions. Buttons that subtly pulse on hover, cards that lift on focus, icons that wobble on click: these micro-interactions add personality without intrusiveness. Use animations with
animation-iteration-count: 1andanimation-fill-mode: forwardsfor "play once and stay" behavior, or transitions for "snap to hover state" patterns. - Attention-drawing CTAs. A primary call-to-action button with a slow, continuous pulse or breathing-glow animation draws the eye without being aggressive. Combine
transform: scale(1) to scale(1.05)withanimation-iteration-count: infiniteand a 3- to 4-second duration for a calm, breathing rhythm. Avoid faster pulses; they feel manic and annoy users quickly. - Page entry and section reveal. Fade-in and slide-up animations on page load or scroll-into-view create polished arrivals. CSS handles the simple case (animations that run once on load); for scroll-triggered entries, IntersectionObserver in JavaScript adds a class that triggers the animation when an element enters the viewport. Modern scroll-driven animations are starting to replace this pattern in pure CSS.
- Success feedback and error shakes. Form submission feedback uses animation cues: a successful save shows a green checkmark with a brief bounce-in animation, while an error shakes the form briefly (
translateXkeyframes alternating -10px and +10px over 0.4 seconds). These small touches make interactions feel responsive and intentional. - Marketing hero and storytelling sequences. Landing pages and hero sections often use staged entry animations (logo fades in, headline slides up, CTA button pulses) to focus attention through a designed sequence. Animation delays (
animation-delay: 0s, 0.3s, 0.6s) on three sibling elements create a staggered effect without needing JavaScript orchestration.
Common pitfalls and what they mean
- Animating layout properties kills performance. Properties like
width,height,margin,padding,top,left,right,bottom, andfont-sizetrigger layout recalculation on every animation frame, often causing jank or below-60fps performance. Usetransform: translateX()instead ofleft,transform: scale()instead ofwidth/height, andopacityinstead ofvisibility. Transform and opacity are GPU-composited and don't trigger layout. - Ignoring prefers-reduced-motion harms accessibility. Some users experience motion sickness or vestibular disorders triggered by web animations. The
prefers-reduced-motion: reducemedia query lets users opt out at the OS level. Wrap your decorative animations in@media (prefers-reduced-motion: no-preference) { ... }or setanimation-duration: 0.01msfor users who request reduced motion. Essential animations (loading spinners) can stay, but decorative ones should respect the preference. - will-change overuse hurts memory. The
will-changeproperty hints to the browser to GPU-promote an element ahead of time, which can smooth animations. But addingwill-changeto many elements consumes significant GPU memory. Apply it only to elements you actually animate, ideally added via JavaScript right before the animation starts and removed afterward. Settingwill-change: transformon every element on the page is an antipattern. - animation-fill-mode confusion. By default, an element returns to its original style after an animation ends. To keep the animation's final state, use
animation-fill-mode: forwards. To start the element in the animation's first state before the delay elapses, usebackwards. To do both, useboth. Many "why does my element snap back?" bugs come from missing this property. The default value isnone, which is rarely what you want for one-shot entry animations. - Infinite animations drain mobile battery. An
animation-iteration-count: infiniteanimation runs forever, keeping the GPU active and the screen refresh rate at its maximum. On mobile devices, this drains battery noticeably. For decorative continuous animations (a logo that gently breathes), consider pausing the animation when the page is hidden (document.visibilityState !== 'visible'), or limiting iteration count to a finite number like 3 to 5 instead of infinite. - Keyframe naming conflicts at scale. @keyframes rule names are global within a stylesheet:
@keyframes fadein one file collides with@keyframes fadein another. For large codebases, namespace your keyframe names (@keyframes app-fade-in,@keyframes hero-slide-up) to avoid silent overrides. CSS modules and CSS-in-JS libraries handle this automatically with scope-hashing.
Privacy: everything runs in your browser
CSS generator tools come in two flavors: simple HTML pages running client-side JavaScript (private, fast) and cloud editors that save your projects (collaborative but with privacy trade-offs). This tool is the first kind. Your slider values, your selected preset, your generated CSS: all stay in your browser session. Refresh the page and the state is gone unless you copied the CSS first. No server stores your animation choices, no analytics tracks which presets you tested, and no account is needed.
The privacy property matters mostly for proprietary design work. A studio prototyping animations for a confidential client project, a developer working on an unannounced app's micro-interactions, or a designer iterating on a brand campaign: any context where the iteration history or in-progress design could leak information about the work. With this tool, there is nothing captured because nothing is sent. Open the browser's Network tab and you will see zero outbound requests during use; only the initial page load fetches the HTML and JavaScript.
When another tool is the right pick
- GSAP for complex sequenced animations. GreenSock Animation Platform (GSAP) handles synchronized, sequenced, scrubbable animations far better than pure CSS. For storyboarded marketing animations, scroll-linked sequences with reverse capability, or anything that depends on JavaScript state changes, GSAP is the industry standard. Free for most use cases (with a club license for some plugins).
- Lottie for designer-authored animations. Lottie (originally from Airbnb) renders After Effects animations as JSON, allowing designers to create complex motion in After Effects and export directly to web/iOS/Android. For animations that exceed what hand-coded keyframes can practically produce (character animations, complex morphing, illustration sequences), Lottie's design-to-code pipeline wins over manual CSS animation.
- Web Animations API for JavaScript control. If you need to start, pause, reverse, or modify animations from JavaScript at runtime, the Web Animations API (
element.animate(keyframes, options)) is more ergonomic than wrangling CSS classes. Returns an Animation object with methods like.pause(),.play(),.reverse(), and a.finishedPromise. Native browser support, no library needed. - requestAnimationFrame for game loops. For animations driven by continuous JavaScript logic (game loops, physics simulations, real-time data visualizations),
requestAnimationFramewith manual per-frame property updates is the right approach. CSS animations are declarative and predefined; rAF gives you per-frame control over what to update. Use Canvas or WebGL when you also need pixel-level control.
Other frequently asked questions
How do I make an animation play only once?
Set animation-iteration-count: 1 (which is the default if not specified). To make the element stay in the animation's final state after it completes (rather than snapping back to the original style), also set animation-fill-mode: forwards. The combined shorthand is animation: fadeIn 0.5s ease-out forwards;.
Can I pause and resume an animation?
Yes, with animation-play-state: paused (or running). Toggle this property via JavaScript (e.g., on a button click) or in CSS via :hover for "pause on hover" patterns. The animation freezes at its current point and resumes from there when set back to running, no progress lost. This works the same in transitions but only the animation-play-state property exists for runtime pause control.
How do I trigger an animation on click or scroll?
For click triggers, toggle a CSS class via JavaScript: element.classList.toggle('animate-in'). The animation runs when the class is added. For scroll triggers, use IntersectionObserver to detect when the element enters the viewport and add the class then. For modern browsers, CSS Scroll-driven Animations let you tie animation progress directly to scroll position without JavaScript via animation-timeline: scroll().
Why does my animation flicker or stutter?
Most flicker/stutter issues come from animating layout-triggering properties (width, height, top/left) instead of transform-based equivalents. Switch left: 0 to transform: translateX(0) and the animation should smooth out. Other causes: overdraw from many semi-transparent layers, layout thrashing from JavaScript reading and writing styles in the same frame, or excessive shadows and filters on the animated element.
Should I use animations on accessibility-critical interfaces?
Use them, but respect prefers-reduced-motion. WCAG 2.1 guidelines recommend providing the option to disable non-essential motion. Wrap decorative animations in @media (prefers-reduced-motion: no-preference) so users who set the OS preference get a static experience. Essential feedback animations (loading indicators, error shakes) can be kept; purely decorative ones should be opt-in for sensitive users.
Can I use cubic-bezier for custom easing curves?
Yes. The cubic-bezier(x1, y1, x2, y2) timing function lets you define any easing curve with two control points. Each x value is between 0 and 1 (representing time), y values can be negative or greater than 1 (allowing overshoot and bounce effects). Use our Cubic Bezier tool or Lea Verou's classic cubic-bezier.com to visually pick a curve. Common preset alternatives: ease, ease-in, ease-out, ease-in-out, and the linear-aliased CSS variables cubic-bezier(0.25, 0.1, 0.25, 1) (default ease).