
CSS Scrolling Images
To avoid burying the lede, animation-timeline
is a magical line of CSS that allows you to animate an element based on the scroll position of the page. If it meets your needs, you can use it to avoid writing JS or adding a library.
Background
I watched a video on CSS Only Scroll-Based Animations and thought it was a fun idea. However, their version was built for the WP site builder and I wanted to see it in regular ol’ code.
They used logos as the example and it caught my attention because I have rearranged logos in so many shapes in the past few years. To be a little different and play with something else, I decided to use images from my recent additions to No ReservAItions.
Code Prep
I’ll share the HTML, but there’s nothing special there. We’ll start with some CSS specifically for ensuring the animation only runs if people don’t opt out of animations. A lot of times this gets sprinkled in at the end, but I like to start with it.
@media (prefers-reduced-motion: no-preference) {
...
}
Now we’ll sprinkle in some HTML and add CSS to handle the basic alignment of them.
(Disclaimer: if you view source, you’ll see some minor code differences but that’s to counter my post styles and to add steps to the shares)
<section class="scroll-wrapper">
<ul class="scroll-container">
<li class="scroll-item">
<img src="/no-reserv-ai-tions/jack-browns.webp" alt="Photo of a burger and fries" />
</li>
<li class="scroll-item">
<img src="/no-reserv-ai-tions/skulls-rainbow-room.webp" alt="Photo of prime rib" />
</li>
<li class="scroll-item">
<img src="/no-reserv-ai-tions/eddie-vs.webp" alt="Photo of a filet mignon" />
</li>
<li class="scroll-item">
<img src="/no-reserv-ai-tions/a-t-o-keeffes.webp" alt="Photo of a burger and fries" />
</li>
</ul>
</section>
.scroll-container {
display: grid;
grid-template-columns: repeat(4, 1fr);
}
@media (prefers-reduced-motion: no-preference) {
...
}
With that, you get some basic images aligned in a grid. Nothing special, but it’s a good start and what people will continue to see if they don’t want animations. In the logos example, he had them scrolling to the side, but for these photos I thought it would be more interesting to see them scale. As you scroll, it looks like that reuben is coming straight for your mouth!
Here comes the magic! It’s wild that one line of CSS now enables this effect. The rest of the styles are for my personal preferences for the animation and the layout. To be safe, I’m using @supports
to ensure the various styles only get applied if the browser supports the feature.
.scroll-container {
display: grid;
grid-template-columns: repeat(4, 1fr);
}
.scroll-wrapper {
overflow: clip;
}
@media (prefers-reduced-motion: no-preference) {
@supports (animation-timeline: view()) {
@keyframes scaleUp {
to {
transform: scale(1.4);
}
}
.scroll-container {
animation: scaleUp ease;
animation-timeline: view(); /* The one magic line */
}
}
}
Oh no! It looks like you're using IE, or at least the modern-day equivalent. Just imagine joyful things and check this out on a browser that supports animation-timeline: view() when you have time.
There’s another little bit that I hadn’t used before, overflow: clip
. I used my standard overflow: hidden
on the wrapper, but that seemed to inhibit the scaling animation. Clipping the overflow to the content box seems to fix it and it was something I picked up in the original video.
Speaking of the original video, they had a second row where they went the opposite scrolling direction. I thought it would be cool to have some images that scaled down instead of up.
This is so much fun! We can debate whether or not this particular effect is useful, but it’s a fun way to play with CSS. I have some similar animations throughout the site, but most of it relies on GSAP.
If I was looking to add this to something for work, I’d probably still want to use GSAP for the animation, mainly because of the browser support. (Or Motion)
I highly recommend playing with some scroll-based animations. This is a super simple example, but Adam Argyle has a notebook that has some fantastic work. And if you’re looking to play with this code, I popped it into a CodePen.