Scroll-driven animation and view transitions without a library

Browsers can now animate page changes and tie animation to scrolling in plain CSS. A practical walkthrough with code, the reduced motion guard, and how to ship it as a safe enhancement.

For years, two kinds of motion meant shipping a JavaScript library: smooth transitions between pages, and animations tied to scrolling. Browsers can now do both in CSS. Less to download, less to break, and when a browser doesn’t support it, the page just works without the flourish.

This one’s a bit more technical than usual. If you’re an owner, the short version is at the bottom.

Cross-page transitions

The View Transition API lets the browser animate from one page to the next (MDN). For a normal multi-page site, both pages opt in with one rule:

@media (prefers-reduced-motion: no-preference) {
  @view-transition {
    navigation: auto;
  }
}

That gives you a default cross-fade between pages on the same site. Wrapping it in the reduced motion check means people who’ve asked their device for less motion get a normal page load instead.

To make one element travel between pages, like a project thumbnail growing into the header image on the detail page, give it the same name on both pages:

.project-card img { view-transition-name: var(--vt-name); }
.project-hero img { view-transition-name: var(--vt-name); }

Set --vt-name to something unique per project (each name can only be used once per page). The browser handles the in-between.

Keep the timing short. A page transition that takes longer than about a third of a second starts to feel like waiting, and that’s a judgment call, not a standard, so test it on yourself.

Scroll-driven animation

Scroll-driven animations tie an animation’s progress to scrolling instead of time (MDN). A common use is a gentle reveal as a section comes into view:

@media (prefers-reduced-motion: no-preference) {
  @supports (animation-timeline: view()) {
    .reveal {
      animation: reveal linear both;
      animation-timeline: view();
      animation-range: entry 0% entry 40%;
    }
  }
}

@keyframes reveal {
  from { opacity: 0.4; transform: translateY(1.5rem); }
  to   { opacity: 1;    transform: none; }
}

Two guards, both important:

  • The reduced motion check, same as above.
  • The @supports check, so a browser that doesn’t know view() doesn’t apply half the rule.

Notice the starting opacity is 0.4, not 0. If something goes wrong, the content is still readable. I never hide content behind an animation.

Keep it cheap

  • Animate transform and opacity. Those are cheap for the browser. Animating width, height or top makes it recalculate the layout on every frame.
  • Don’t animate everything. One or two reveal patterns used consistently read as design. Every element sliding in reads as noise.
  • Test on a mid-range phone. If scrolling stutters, cut back.

What our own site does

Our current site uses a small library for its page transitions, because native cross-page transitions weren’t as widely supported when we built it. New builds start with the native CSS above and only reach for a library when a design really needs choreography CSS can’t do. The rules for the heavier stuff, like our WebGL hero, are in Motion graphics on a small-business site.

For owners: the short version

  • Your site can have app-like transitions without the weight that used to come with them.
  • Built properly, browsers that don’t support it just load the page normally.
  • Motion should always respect a visitor’s reduced motion setting.
  • If your current site feels sluggish because of animation, that’s usually fixable without a redesign.

More on where this fits in the bigger picture: Web design for 2027. If you’d like us to look at yours, let me know. Thanks!

FAQ

Frequently asked questions.

The questions clients ask most after reading this.

Do I still need GSAP or another animation library?

For simple page transitions and scroll reveals, often not. Native CSS handles them with no download. Complex timelines, physics or heavy choreography are still easier with a library, and that is a fine reason to use one.

What happens in a browser that does not support these features?

Built as an enhancement, nothing breaks. The page loads normally without the transition, and elements that would have animated simply appear in their final state.

Are scroll animations bad for accessibility?

They can be, for people sensitive to motion. Wrap them in a prefers-reduced-motion check so they only run for people who have not asked for less motion, and never hide content until an animation finishes.

More development reading

Related from the lab.

All field notes

Can AI help?

What's the task your team does manually every day?

Tell us in plain words. We'll ask a couple of questions, then tell you honestly whether it's worth automating — no sales pitch.