Sensible Use Instances for Scroll-Linked Animations in CSS with Scroll Timelines

No Comments

The Scroll-Linked Animations specification is an upcoming and experimental addition to CSS. Utilizing the @scroll-timeline at-rule and animation-timeline property this specification gives you possibly can management the time place of normal CSS Animations by scrolling.

On this submit, we check out some sensible use instances the place scroll-linked animations turn out to be useful, changing a typical JavaScript method.

👨‍🔬 The CSS options described on this submit are nonetheless experimental and never finalized in any respect. The should not supported by any browser on the time of writing, apart from Chromium ≥ 89 with the #experimental-web-platform-features flag enabled.

CSS Scroll-Linked Animations, a fast primer

With CSS Scroll-Linked Animations, you possibly can drive a CSS animation by scroll: as you scroll up or down inside a scroll container, the linked CSS animation will advance or rewind. Better of all is that that is all working off primary thread, on the compositor.

You want three issues to implement a fundamental scroll-linked animation:

a CSS animationa scroll timelinea hyperlink between each

CSS animation

This can be a common CSS Animation like we already know:

@keyframes adjust-progressbar {
from {
remodel: scaleX(0);
to {
remodel: scaleX(1);

As you usually do, connect it to a component utilizing the animation property:

#progressbar {
animation: 1s linear forwards adjust-progressbar;

Scroll timeline

The scroll timeline permits us to map the scroll distance to the animation progress. In CSS, we describe this with the CSS @scroll-timeline at-rule.

@scroll-timeline scroll-in-document-timeline {
supply: auto;
orientation: vertical;
scroll-offsets: 0%, 100%;

This at-rule consists of descriptors, together with:

The supply describes the scrollable factor whose scrolling triggers the activation and drives the progress of the timeline. By default, that is your entire doc.The orientation determines the scrolling route that ought to set off the animation. By default, that is vertical.The scroll-offsets property is an array of key factors that describe the vary by which the animation needs to be energetic. It may be absolute values (e.g. percentages and lengths) or element-based.

A earlier model of the specification required you to additionally set a time-range descriptor. This descriptor has been eliminated and can robotically take over the animation-duration from the linked animation. You should still see traces of it within the demos, however you possibly can safely ignore it.

A hyperlink between each

To affiliate our @scroll-timeline with our CSS animation, we use the brand new animation-timeline CSS property, and have it confer with the timeline’s identify.

#progressbar {
animation: 1s linear forwards adjust-progressbar;
animation-timeline: scroll-in-document-timeline; /* 👈 THIS! */

With that arrange the adjust-progressbar animation gained’t run robotically on web page load, however will solely advance as we scroll down the web page.

CodePen Embed Fallback

For a extra in-depth introduction to @scroll-timeline please confer with Half 1 and Half 2 of my sequence on the way forward for scroll-linked animations.

The first submit appears at every descriptor/property in additional element, explaining them with an instance to associate with them, earlier than overlaying many extra attention-grabbing demos.

The second submit digs even deeper, trying into Aspect-Based mostly Offsets, which permit us to drive an animation as a component seems into and disappears from the scrollport as we scroll.

An instance of what you possibly can obtain with CSS Scroll-Linked Animations utilizing Aspect-Based mostly Offsets.

Sensible use instances

Other than the progress par demo above, there are just a few extra use instances or situations the place scroll-linked animations can exchange an answer sometimes carried out utilizing JavaScript.

parallax headerimage reveal/hidetyping animationcarousel indicatorsscrollspy

Parallax header

A typical use case for Scroll-Linked Animations is a parallax impact, the place a number of sections of a web page appear to have a special scrolling velocity. There’s a method to create these sort of results utilizing solely CSS, however that requires mind-bending remodel hacks involving translate-z() and scale().

Impressed upon the Firewatch Header—which makes use of the talked about remodel hack—I created this model that makes use of a CSS scroll timeline:

CodePen Embed Fallback

In comparison with the unique demo:

The markup was stored, apart from that further .parallax__cover that’s now not wanted.The <physique> was given a min-height to create some scroll-estate.The positioning of the .parallax factor and its .parallax_layer youngster components was tweaked.The remodel/perspective-hack was changed with a scroll timeline.

Every totally different layer makes use of the identical scroll timeline: scroll over a distance of 100vh.

@scroll-timeline scroll-for-100vh {
time-range: 1s;
scroll-offsets: 0, 100vh;

.parallax__layer {
animation: 1s parallax linear;
animation-timeline: scroll-for-100vh;

What’s totally different between layers is the space that they transfer as we scroll down:

The foremost layer ought to keep in place, eg. transfer for 0vh.The final layer ought to ought to transfer the quickest, e.g. 100vh.All layers in between are interpolated.

@keyframes parallax {
to {
remodel: translateY(var(–offset));

.parallax__layer__0 {
–offset: 100vh;

.parallax__layer__1 {
–offset: 83vh;

.parallax__layer__2 {
–offset: 67vh;

.parallax__layer__3 {
–offset: 50vh;

.parallax__layer__4 {
–offset: 34vh;

.parallax__layer__5 {
–offset: 17vh;

.parallax__layer__6 {
–offset: 0vh;

Because the foremost layers transfer over a better distance, they seem to maneuver quicker than the decrease layers, attaining the parallax impact.

Picture reveal/disguise

One other nice use-case for scroll linked animations is a picture reveal: a picture slides into view because it seems.

CodePen Embed Fallback

By default, the picture is given an opacity of 0 and is masked utilizing a clip-path:

#revealing-image {
opacity: 0;
clip-path: inset(45% 20% 45% 20%);

Ultimately-state we wish the picture to be totally seen, so we despatched the end-frame of our animation to replicate that:

@keyframes reveal {
to {
clip-path: inset(0% 0% 0% 0%);
opacity: 1;

Through the use of element-based offsets as our scroll timeline offsets, we are able to have it so thar the picture begins to seem solely when the picture itself slides into view.

@scroll-timeline revealing-image-timeline {
selector(#revealing-image) finish 0.5,
selector(#revealing-image) finish 1

#revealing-image {
animation: reveal 1s linear forwards;
animation-timeline: revealing-image-timeline;

😵 Can’t comply with with these element-based offsets? This visualization/software has acquired you coated.

Typing animation

As CSS scroll timelines might be linked to any current CSS animation, you possibly can mainly take any CSS Animation demo and remodel it. Take this typing animation for instance:

CodePen Embed Fallback

With the addition of a scroll timeline and the animation-timeline property, it may be adjusted to “sort on scroll”:

CodePen Embed Fallback

Be aware that to create some scroll-estate the <physique>was additionally given a peak of 300vh.

Utilizing a special animation, the code above can simply be adjusted to create a zoom on scroll impact:

CodePen Embed Fallback

I can see these two working nice for article intros.

Carousel/Slider indicators

One of many parts of a carousel (aka slider) is an indicator that exposes what number of slides it comprises, in addition to which slide is at the moment energetic. That is sometimes achieved utilizing bullets.

This once more is one thing we can obtain utilizing a CSS scroll timeline, as proven on this demo created by Fabrizio Calderan:

CodePen Embed Fallback

The energetic state bullet is injected by way of .slider nav::earlier than and has an animation set that strikes it over the opposite bullets

/* Styling of the dots */
.slider nav::earlier than, .slider a {
inline-size: 1rem;
aspect-ratio: 1;
border-radius: 50%;
background: #9bc;

/* Positioning of the energetic dot */
.slider nav::earlier than {
content material: “”;
place: absolute;
z-index: 1;
show: block;
cursor: not-allowed;
remodel: translateX(0);
animation: dot 1s steps(1, finish) 0s forwards;

/* Place over time of the energetic dot */
@keyframes dot {
{ remodel: translateX(0); }
{ remodel: translateX(calc((100% + var(–gap)) * 1)); }
{ remodel: translateX(calc((100% + var(–gap)) * 2)); }
{ remodel: translateX(calc((100% + var(–gap)) * 3)); }

By attaching a @scroll-timeline onto the slider, the dot that signifies the energetic state can transfer as you scroll:

@scroll-timeline slide {
supply: selector(#s);
orientation: inline;

.slider nav::earlier than {
/* and many others. */
animation-timeline: slide;

The dot solely strikes after the slide has snapped to its place because of the inclusion of a steps() perform within the animation. When eradicating it, it turns into extra clear how the dot strikes as you scroll

CodePen Embed Fallback

💡 This looks like the ultimate lacking piece to Christian Shaefer’s CSS-only carousel.


Again in early 2020, I created a sticky desk of contents with scrolling energetic states. The ultimate half to creating the demo was to make use of IntersectionObserver to set the energetic states within the desk of contents (ToC) as you scroll up/down the doc.

CodePen Embed Fallback

In contrast to the carousel indicators demo from above we are able to’t merely get there by transferring a single dot round, because it’s the texts within the ToC that get adjusted. To method this example, we have to connect two animations onto every factor within the ToC:

The primary animation is to visually activate the ToC merchandise when the right part comes into view on the backside fringe of the doc.The second animation is to visually deactivate the ToC merchandise when the right part slides out of view on the prime fringe of the doc.

.section-nav li > a {
1s activate-on-enter linear forwards,
1s deactivate-on-leave linear forwards;

As we’ve got two animations, we additionally must create two scroll timelines, and this for every part of the content material. Take the #introduction part for instance:

@scroll-timeline section-introduction-enter {
supply: auto;
selector(#introduction) finish 0,
selector(#introduction) finish 1;

@scroll-timeline section-introduction-leave {
supply: auto;
selector(#introduction) begin 1,
selector(#introduction) begin 0;

As soon as each of those timelines are linked to each animations, all the pieces will work as anticipated:

.section-nav li > a[href”#introduction”] {

In closing

I hope I’ve satisfied you of the potential supplied by the CSS Scroll-linked Animations specification. Sadly, it’s solely supported in Chromium-based browsers proper now, hidden behind a flag.

Given this potential, I personally hope that—as soon as the specification settles onto a sure syntax—different browser distributors will comply with go well with. Should you too want to see Scroll-Linked Animations land in different browsers, you possibly can actively star/comply with the related browser points.


By actively starring points, us builders can sign our curiosity into these options to browser distributors.

The submit Sensible Use Instances for Scroll-Linked Animations in CSS with Scroll Timelines appeared first on CSS-Tips. You may help CSS-Tips by being an MVP Supporter.

    About Marketing Solution Australia

    We are a digital marketing company with a focus on helping our customers achieve great results across several key areas.

    Request a free quote

    We offer professional SEO services that help websites increase their organic search score drastically in order to compete for the highest rankings even when it comes to highly competitive keywords.

    Subscribe to our newsletter!

    More from our blog

    See all posts

    Leave a Comment