Honey Butter

CSS Is Coming for Your Scroll Animations (Politely)

Categories

For years, animation on the web has lived in a delicate truce.

CSS handled the simple stuff – transitions, keyframes, hover states.
JavaScript handled the good stuff – scroll-based animation, timelines, orchestration, and nuance. That division is about to blur in a big way.

Enter CSS progress() – an upcoming feature that gives CSS something it’s never truly had before: awareness of progress. And once CSS understands progress, animation becomes a very different conversation.

The Core Problem CSS Has Always Had

CSS animations have always been time-based, not state-based.

You could say:

  • “Animate this over 1s”
  • “Ease it like this”
  • “Loop it forever”

But you couldn’t say:

  • “Animate this as the user scrolls
  • “Tie this value to how far something has progressed
  • “Map one motion directly to another”

JavaScript libraries (GSAP especially) stepped in to fill that gap – and did it brilliantly.

CSS progress() is the browser saying:

“We can do that now.”

What Is progress()?

At a high level, progress() exposes a normalized 0 → 1 value representing how far something has progressed through a defined range.

That range might be:

  • Scroll position
  • An animation timeline
  • A view-based interaction
  • A container’s visibility

Instead of calculating progress in JavaScript, CSS can now react to it directly.

Think of it as CSS finally getting a slider knob.

A Simple Mental Model

Imagine this:

opacity: progress(scroll) * 1;
transform: translateY(progress(scroll) * 100px);

That’s not final syntax – but conceptually, that’s what’s happening.

  • At the start → progress() = 0
  • At the end → progress() = 1
  • Everything in between is smoothly interpolated

No scroll listeners
No requestAnimationFrame
No math in JS
No sync issues

Just… CSS.

Why This Is a Big Deal for Animation

1. CSS Becomes Reactive (Not Just Decorative)

This is the real shift.

CSS has traditionally reacted to state changes:

  • hover
  • focus
  • active
  • media queries

progress() makes CSS reactive to continuous input.

That’s enormous.

Scroll-driven fades, parallax, reveals, counters, transforms – all become native, declarative behaviors.

2. Animations Become Easier to Reason About

When animation logic lives in JS:

  • You manage lifecycle
  • You manage cleanup
  • You manage timing and sync
  • You manage resize edge cases

With progress():

  • The browser owns the timing
  • The browser owns the sync
  • The browser owns invalidation

You describe what should happen, not how to compute it.

That’s a massive cognitive win.

3. Performance Is Likely to Be Better (Yes, Really)

Short answer: yes – in most cases, it will perform better.

Why?

Because:

  • It runs closer to the rendering engine
  • It avoids JS → layout → paint feedback loops
  • It can be optimized at the compositor level
  • It avoids main-thread JavaScript work during scroll

JavaScript animation libraries are incredibly optimized – GSAP especially – but they still have to run JavaScript.

Native CSS progress-based animation:

  • Requires no JS execution per frame
  • Can skip frames intelligently
  • Can be hardware-accelerated more predictably

This matters most on:

  • Low-power devices
  • Long scrolling pages
  • Heavy DOM environments
  • Embedded or constrained contexts

So… Does This Kill GSAP?

No. Not even close. And this is important.

GSAP Still Wins At:

  • Complex timelines
  • Sequenced choreography
  • Physics-based motion
  • Cross-property orchestration
  • Dynamic runtime logic
  • Audio-synced animation
  • Highly interactive games & experiences

What progress() does is eliminate the need for JS in a huge class of animations that should never have required it in the first place.

Think:

  • Scroll fades
  • Parallax layers
  • Simple reveals
  • Progress-based transforms
  • Viewport-driven effects

That’s not replacing GSAP – that’s freeing it to be used where it actually shines.

Why “Less JavaScript” Is a Good Thing (Even If You Love JS)

This isn’t about ideology.
It’s about fit for purpose.

If the browser can do something natively:

  • It’s usually more stable
  • It’s usually more accessible
  • It’s usually more performant
  • It’s usually easier to maintain

Using JavaScript for animation when CSS can do it natively is like using a power tool to turn a screw.

Fun? Yes.
Necessary? No.

The Bigger Picture: CSS Is Growing Up

Between:

  • @scroll-timeline
  • view-timeline
  • container queries
  • has()
  • and now progress()

CSS is no longer just a styling language.

It’s becoming a behavioral language.

Not a replacement for JavaScript – but a partner that finally pulls its weight.