CSS Continues to Struggle with Animation Sequences and Staggers

The GSAP vs CSS Animations rivalry has been going on for over a decade. 

Having spent many years following the advancements in both technologies I can safely assert that CSS is still quite terrible for sequences and staggers. 

This isn't an attack on the people who love CSS and expertly milk every bit of power out of it. 

It's just the way it is.

Sure, there have been advancements with animating stroke-dashArray, clip-paths, objects on a path, height:auto and other properties which are great for "one-off" effects and state-changes.

Animated view transitions and rudimentary scroll-driven animation support are also big steps forward for CSS.

In 2026 sequencing remains the weak point of CSS

The main reason being: it wasn't designed for this from the beginning and virtually nothing has been done to make sequencing any easier.

On the other hand, creating a stagger effect has seen some improvement.



CSS sibling-index()

The fairly new sibling-index() CSS function opens up some powerful styling and animation capabilities.

Simply put, sibling-index() informs you of where an element sits among its neighboring DOM elements.

To create staggered CSS animations you can access the sibling-index() value to dynamically offset the animation-delay.


CSS Code

.letter {
    animation-delay: calc(sibling-index() * 0.2s);
}

With the code above, the first ".letter" would have an animation delay of 0.2, and the second a delay of 0.4.

It's important to note that the first item's index is 1 and not 0 (as it would with a JS array).


CSS Stagger Animation

NOTE: as of July 2026 these CSS functions are not available in Firefox. Use current Chrome, Edge or Safari

It's pretty nice that this works, but there is considerably way more code than we would need to do the same with GSAP.

I tapped into the Web Animations API to cancel() and play() the animations on all the letters.

Unfortunately for those who avoid GSAP because they don't like JavaScript, this is a non-trivial undertaking.

Be sure to view the CSS and JS code panels to see how it is set up.



CSS sibling-count()

The sibling-count() function which returns the number of siblings provides for some additional wins.

I was able to subtract the sibling-index() from sibling-count() to create a stagger that starts at the last element.


CSS Code

.letter { 
  animation-delay: calc((sibling-count() - sibling-index()) * 0.2s); 
}


This equation causes the animation-delays to decrease from left-to-right making the end letters start sooner than the letters at the start of the line.


CSS Reverse Stagger

NOTE: as of July 2026 these CSS functions are not available in Firefox. Use current Chrome, Edge or Safari

I'm certain some top experts and math whizzes will be able to create some interesting effects with these new functions.

Although these methods open up new potential for CSS staggers, they break down quickly if you want to sequence them with other animations, add controls (play, pause, reverse) or go beyond a few basic configurations (without going into genius-mode).




GSAP was Born to Sequence

From its inception GSAP was designed to give professionals fine-tuned control over every animation in a way that beginners can easily grasp and master.


Two of GSAP's greatest strengths are:

  1. Staggering animations of multiple elements as seen in many text effects.
  2. Sequencing animations in timelines.


With GSAP's staggers you can easily configure the amount of overlap and the direction from which the staggers start.

Stagger code

stagger:{
  each:0.1,
  from:"center"
}

With this code each element in a tween starts 0.1 second after the previous element. If the code were applied to multiple letters in a word they would animate from the center of the word as shown with the word "Terrible" in the example below.

Other from values to use: "edges", "end", "random", and "start" (default).

No cryptic calculations needed.

Read More about GSAP Staggers on Codrops

When using GSAP's timelines all animations will naturally follow one-after-the-other while also allowing for precise overlaps and gaps.

Let's consider a few basic GSAP examples that would still be problematic with CSS in 2026.


Basic GSAP Stagger Sequence

In the example above, each line animates in one after the other.

GSAP naturally aligns these animations in sequence, but with CSS you would have to know the full duration of the first line to use as the delay of the animation of the 2nd line.

The third line's animation would have to have its delay set to the sum of the durations of the first and second line.

Keep in mind each line has different numbers of characters which makes each duration different.

What a nightmare!

In addition, doing a simple "click to restart" of a css animation sequence like the one above would be a challenge to beginners.



Multiple Staggers with Same Duration

In the demo above each line starts and ends at the exact same time even though there are different numbers of characters in each line.

The secret here is that each tween in the timeline has its stagger amount set to 1 second.

Study the timeline defaults code:

const tl = gsap.timeline({
  defaults:{
    duration:1, 
    stagger:{
      amount:1, 
      from:"edges"
    }
  }
})

By setting stagger amount to 1 it means that each staggered element in each tween will start within 1 second.

The last character to animate in each line will start at a time of 1 second.

Whether a line has 10 or 30 characters, GSAP will distribute the start times to make sure the first character starts at time:0 and the last one starts at time:1.

Since all the characters in each line have the same duration, the LAST characters in each line will start and end at the same time 🚀 

I set from:"edges" just to show off a bit ✨ 

The timeline is just 3 simple tweens sharing the same default stagger values:

.from(splits[0].chars, {yPercent: 100}, 0)
.from(splits[1].chars, {yPercent: 100}, 0)
.from(splits[2].chars, {yPercent: 100}, 0)

This animation may be easier to do with CSS as there is no need to manage delays for each line. It really isn't a "sequence" of multiple animations since they all start at the same time.

I suspect one crazy formula with sibling-index() and sibling-count() could be re-used for the animation of each line.

However, that would take some considerable time and mental horsepower.

GSAP makes this virtually effortless to create within minutes.

If all this talk of tweens, timelines, and staggers is completely foreign to you, jump on into my FREE GSAP Beginner's Course. It will get you up and running with quickly with GSAP.


Bonus Challenges

I created the demos below to show you some additional stagger effects that illustrate some of the more advanced features of GSAP.


Feel free to fork this demo and try to recreate the bonus effects above using GSAP or CSS.

The first line with the bounce is fairly easy for intermediate users (hint: tweenTo()) but the second one would probably have some pros scratching their heads.

Notice how the characters at the end of the animation travel further with a longer duration.

Hint: I hack into ease curves to get increasing values to distribute throughout the various properties of the animations.


That video is 5 years old. 

Tricks like this are nothing new, but very few people know these features exist or how to use them.

GSAP gives professional animators the flexibility they need to go way beyond the limitations of CSS and other JS tools.

Again, CSS simply wasn't created with these types of animations in mind.


Share with Friends

Feel free to share this with your front-end dev pals the next time the "CSS animations vs GSAP/JavaScript" discussion comes up. 

Offer a friendly challenge to build the first two basic animations on this page. Demo 1 || Demo 2

I'd be happy to post CSS versions of these animations for comparison if anyone wants to contribute. 


Conclusion

CSS is of course an integral part of the web and responsible for many of the great UI features we have today (flex-box, grid, media queries, scroll-snapping, anchor positioning, container query units, etc). 

I have great respect for those that can expertly harness its amazing capabilities.

IMHO CSS just doesn't hold up very well when you need to go beyond singular animated state changes.

Although CSS may be catching up with stagger effects, it's still light-years behind when it comes to sequencing.



Go deeper with GSAP

I spent nearly 8 years working at GreenSock (now GSAP) creating documentation, training videos, demos, and answering thousands of support questions. 

Since working there I've spent nearly 6 years archiving everything I know about GSAP in my extensive Creative Coding Club courses.

You'll learn loads of tips and tricks that will save you hours of trouble trying to do it on your own.

I'll help you de-mystify powerful features that are hiding deep inside the documentation and show you how they can help you solve real-world animation challenges.

Check out these reviews and learn why this training is the Number 1 Choice for GSAP training across the globe. 

Join today and start mastering GSAP