CSS Motion Tool

Scroll Animation Keyframe Builder

Build scroll-driven animations visually. Edit keyframes, set the timeline range and easing, then copy pure-CSS scroll animations — or an IntersectionObserver fallback that works everywhere.

  • Keyframe Editor
  • Scroll Timeline
  • Live Scrubber
  • No JS Needed
  • Free
  • No Signup

Controls

Output mode

Pure CSS, no JavaScript. Chrome and Edge 115+ and recent Firefox; Safari falls back to the finished state.

Used for both the @keyframes name and the CSS class.

Presets
Keyframes

A new stop takes the value already interpolated there, so adding one changes nothing until you move a slider.

Timeline

Linear usually reads best for scroll-linked motion — the visitor's own scrolling supplies the pacing.

Demo element
Stagger & options

Both safety blocks are on by default. Turning them off is a real decision, not a cosmetic one.

Preview

↓ scroll inside this frame
↑ scroll back up
0%

The preview interpolates your keyframes in JavaScript so it looks the same in every browser — including ones that cannot run the CSS this tool generates. The exported code is the real thing.

Browser support & safety

    Generated code

    0 lines

    Your work never leaves this browser. The autosave writes to your own local storage only — no account, no upload.

    What Is a Scroll Animation?

    A scroll animation is motion driven by scroll position instead of by a clock. As the visitor scrolls, an element fades in, slides up, scales, rotates or blurs. Three patterns cover almost every real use:

    • Reveal. Content animates in once as it enters the viewport. The most common, and the least risky.
    • Scroll-linked. The animation's progress is tied to scroll position in both directions — scroll up and it rewinds. Progress bars and parallax live here.
    • Stagger. A group of items animates in sequence rather than together, which reads as one deliberate movement instead of a jolt.

    Until recently all of this needed JavaScript. CSS scroll-driven animations changed that: you write ordinary @keyframes and then tell the browser to drive them from the scrollbar rather than from time. No scroll listeners, no layout thrash, and the animation can run off the main thread.

    How Scroll-Driven CSS Works

    Two extra properties turn a normal animation into a scroll-driven one:

    @keyframes fade-up {
      0%   { opacity: 0; transform: translate3d(0px, 48px, 0); }
      100% { opacity: 1; transform: none; }
    }
    
    .fade-up {
      animation: fade-up linear both;
      animation-timeline: view(block);      /* drive from scroll, not time */
      animation-range: entry 0% cover 40%;  /* which part of the journey  */
    }

    animation-timeline swaps the clock for a scroll position. view() follows this element's own trip across the viewport; scroll() follows a scroll container's scrollbar, which is what a page-wide progress bar wants. Note there is no duration — the scroll supplies it.

    animation-range decides which slice of that journey the animation occupies. entry 0% cover 40% means "start the moment the element first pokes into view, and be finished by the time it is 40% of the way across".

    Timeline & Range Reference

    ValueWhat it meansUse it for
    view()Timeline follows this element across the viewport.Reveals, parallax, per-block motion.
    scroll()Timeline follows a scroll container's scrollbar.Reading progress bars, page-wide effects.
    entryFrom first pixel entering to fully entered.Fade and slide reveals.
    exitFrom starting to leave to fully gone.Fade-outs as content scrolls away.
    coverThe whole journey — first touch to last.Parallax and long scroll-linked motion.
    containOnly while the element is fully visible.Effects that should not run at the edges.
    animation-rangeStart phase and offset, then end phase and offset.Tuning exactly when motion starts and stops.
    animation-fill-modeWhether the first and last keyframes persist outside the range.both is almost always what you want.
    @supports notDetects browsers without scroll timelines.Showing the finished state instead of a blank space.

    Accessibility and Performance

    Scroll animation is one of the few CSS features with a documented health impact. Motion tied to scrolling — parallax especially — is a known trigger for nausea, dizziness and migraine in people with vestibular disorders. Two rules follow from that:

    Always ship reduced-motion

    A prefers-reduced-motion: reduce block that removes the animation entirely. It is on by default here and worth keeping.

    Keep travel small

    Long slides and big parallax offsets cause the most discomfort — and the most horizontal overflow on narrow screens.

    Never hide content behind motion

    If the animation fails, the content must still be readable. That is exactly what the @supports fallback guarantees.

    Animate transform and opacity

    These can be handled by the compositor. Animating width, height, top or blur forces work every frame.

    Prefer CSS over scroll listeners

    Native scroll-driven animations avoid the layout thrash a JavaScript scroll handler tends to cause.

    Use motion sparingly

    When everything animates, nothing stands out and the page feels slow to read.

    Use Cases

    Landing page reveals

    Sections fade and rise as they enter view — the most common scroll animation on the web.

    Reading progress bars

    A scroll() timeline scaling a bar from the left as the article is read.

    Staggered feature lists

    Items arriving in sequence, which reads as one movement rather than a jolt.

    Parallax hero images

    Background art drifting slower than the foreground for a sense of depth.

    Image galleries

    Photos scaling gently into place as they cross the viewport.

    Product storytelling

    Long-scroll pages where each step animates as the reader arrives at it.

    Sticky section headers

    Headings that shrink or fade as their section scrolls past.

    Portfolio case studies

    Considered motion that shows craft without getting in the way of the work.

    Frequently Asked Questions

    What is a scroll animation?

    A scroll animation is motion tied to scroll position rather than to a clock. As the visitor scrolls, an element fades, moves, scales or rotates. It is used to reveal content as it enters the viewport, to drive progress bars, and to create parallax depth.

    How do I create a scroll animation in CSS?

    Write an @keyframes block describing the start and end state, apply it with the animation property, then set animation-timeline to view() or scroll() instead of relying on a duration. The browser then drives the animation from scroll position rather than from time.

    What is animation-timeline?

    animation-timeline replaces the default time-based clock of a CSS animation with a scroll-based one. Set it to scroll() to follow a scroll container's scrollbar, or to view() to follow the element's own progress through the viewport.

    What is the difference between scroll() and view()?

    scroll() tracks how far a scroll container has been scrolled, so it is right for page-level things such as a reading progress bar. view() tracks one element's journey across the viewport, so it is right for reveals and parallax on individual blocks.

    What is animation-range?

    animation-range says which part of the timeline the animation occupies. entry covers the element coming into view, exit covers it leaving, cover spans the whole journey from first touch to last, and contain spans only the time it is fully visible. Each takes a percentage offset.

    Do CSS scroll animations work in all browsers?

    No. Scroll-driven animations ship in Chrome and Edge 115 and later and in recent Firefox, but Safari does not support them yet. That is why this tool generates an @supports fallback by default and offers an IntersectionObserver mode that works everywhere.

    What happens in browsers that do not support scroll timelines?

    The animation-timeline declaration is ignored and the animation would otherwise run once on a normal clock or leave the element stuck at its first keyframe. The generated @supports not block prevents that by showing the finished state, so content that starts at opacity 0 can never stay invisible.

    Should I use IntersectionObserver or CSS scroll timelines?

    Use CSS scroll timelines when the motion should track scroll position both ways, and you are happy for Safari to see the finished state. Use IntersectionObserver when you need a reliable one-shot reveal in every browser today. The tool generates both.

    How do I animate an element on scroll without JavaScript?

    Choose one of the two scroll-driven modes. Those generate CSS only — an @keyframes block plus animation-timeline and animation-range. No script is involved, which is why they keep working even if your JavaScript fails to load.

    How do I stagger a list of items?

    Turn on Stagger and set the step. In IntersectionObserver mode the tool emits nth-child rules with increasing animation-delay. In scroll-driven mode it shifts each child's animation-range instead, so the offset stays tied to scroll position rather than to time.

    What easing should I use for scroll animations?

    Linear usually feels best for scroll-linked motion, because the visitor's own scrolling already supplies the pacing and an eased curve can feel like lag. Save the softer curves for one-shot reveals, where the animation runs on its own clock.

    Are scroll animations bad for accessibility?

    They can be. Motion tied to scrolling is a known trigger for nausea, dizziness and migraine. Always ship a prefers-reduced-motion block that removes the animation, which this tool includes by default, and avoid large travel distances and parallax on essential content.

    Do scroll animations hurt performance?

    Native scroll-driven animations run off the main thread when they animate only transform and opacity, which makes them cheaper than a scroll event listener. Animating blur, width or height forces work on every frame, so keep those for short, small elements.

    Can I use this for a reading progress bar?

    Yes. Pick the Progress bar preset, which switches to the scroll() timeline and scales the bar horizontally from a left transform origin as the page scrolls.

    Can I create a parallax effect?

    Yes. The Parallax preset moves the element in the opposite direction to the scroll across the whole cover range. Keep the travel small, because large parallax offsets are the most common cause of motion discomfort.

    Does the preview use the generated CSS?

    No, and that is deliberate. The preview interpolates your keyframes in JavaScript so it looks the same in every browser, including ones that cannot run scroll-driven CSS at all. The maths mirrors what a browser does, but the exported CSS is the real thing.

    Can I add more than two keyframes?

    Yes, up to twelve stops. A new stop is created at the currently previewed position and takes the interpolated value there, so adding one changes nothing until you move a slider.

    Is this scroll animation generator free?

    Yes. It is free, needs no account, and has no export limits or watermarks. The generated CSS is ordinary CSS you can use in commercial work without attribution.

    Is my work uploaded anywhere?

    No. The builder runs entirely in your browser. The autosave writes to your own browser storage only, and nothing is sent to a server.