Animation-Driven Scrolls
- Published on:
- Categories:
- scroll-snap 2, CSS 94, Observation 10
- Current music:
- James Primate —
RW_48 - Wind Chimes
- Current drink:
- Peppermint Tea
Past Experiments
Three years ago, I posted my “Observation: Snappy Scroll-Start” post on this blog. There, I talked about how we can use scroll-snap and a one-time animation to emulate the scroll-start. Since then, that property’s proposal from Adam Argyle (I first properly learned about scroll-snap from his “Oh Snap!” talk at CSS Day 2022) did not go anywhere yet, but we at least got scroll-initial-target which works kinda like what I did in my experiment from 2023, but only in Chrome for now.
Since then, I did experiment a bit more with this combo — animations & scroll-snap, and there was one idea I experimented in 2024 with that I never fully finished.
Yesterday, I was reminded about these experiments by Lyra Rebane in Mastodon (I stole the name for this post from her), and decided to at least publish something quick, more fitting into my “observation” tag rather than a fully fledged technique.
The Idea
The idea is pretty simple: what if we had an overflowing container, inside which we would have an element with scroll-snap, and then we animated the position of this element?
Toggle this below to start the animation:
I won’t post the full CSS for this example, it is messy and a lot of it is not related to the effect itself, but the crucial parts are:
.container {
overflow: auto;
scroll-snap-type: both mandatory;
}
.anchor {
position: absolute;
scroll-snap-align: center;
animation:
--move-x 3.1s linear infinite alternate,
--move-y 1.1s linear infinite alternate
;
}
@keyframes --move-x {
from { left: calc(50cqw + 1em); }
to { left: calc(100% - 50cqw - 1em); }
}
@keyframes --move-y {
from { top: calc(50cqh + 1em); }
to { top: calc(100% - 50cqh - 1em); }
}
Interestingly, if we were to replace this with a transform, it will still work, but will be much more choppy in Firefox and Chrome, and won’t work at all in Safari (even the anchor will disappear) — I guess that’s the difference between timings of scroll/snap/transform:
What Can We Do With This?
Not sure! In production, likely not much. It feels like scroll-snap is pretty buggy all around when animations are involved — I will need to find spoons to reproduce some of the things I saw.
But I have a few ideas of further experiments, and if you want, you can join me, and do some of them before me — less work for me!
For example, instead of animations, we could use transitions. Or we could maybe even add scroll-driven animations, like use this for “delegating” scroll from one container into another… Or use it for something like a guided tour over something like a map. But I imagine without proper and smooth transforms support, the offset-path won’t work well too, and it might be painful trying to reproduce it with just animations of inset properties… Unless we add anchor positioning maybe, as it can be transitioned? And — with anchor positioning soon being able to follow transforms, could we anchor something to an element with an animated transform, and then snap our scroll to that anchor…
Anyways. The above is the thoughts I usually get when I look at some CSS feature, and I wish I could explore this full-time, and not just in a few hours after work.