Here’s a rewritten version of the article with clearer structure and simplified language, while preserving all the technical details:

Modern Scroll Shadows with Scroll-Driven Animations

Scroll shadows are a subtle but effective UX enhancement, especially useful on mobile devices. Chris Coyier has long championed scroll shadows as one of his favorite CSS tricks. Traditionally, they’re created using layered background gradients that fade out when the user scrolls to the edges of an element.

More recently, Geoff Graham introduced a modern technique using the animation-timeline property, which allows CSS animations to respond directly to scroll position. In his approach, scroll shadows are created using pseudo-elements, with their opacity animated based on scroll progress via animation-range.

But there’s another elegant solution — instead of shadows, we can use a CSS mask to fade the edges of a scrollable container. This gives a similar visual cue without needing visible borders or overlays. It’s especially useful for horizontally scrollable elements, like wide tables on mobile, and works seamlessly on both light and dark backgrounds.

Step 1: Create a Fading Mask for the Scrollable Element

Let’s start by applying a CSS mask to our scrollable element. This will fade the content at both the left and right edges using a linear gradient:

.scrollable {
mask: linear-gradient(to right, #0000, #ffff 3rem calc(100% – 3rem), #0000);
}

This creates a mask that’s fully transparent at the start and end (using #0000), and fully opaque in the middle. The mask fades in over 3rem from each edge.

Step 2: Define Custom Properties and Animation

To animate the fading effect based on scroll position, we’ll define two custom CSS properties: –left-fade and –right-fade. These will be animated using a scroll-driven animation.

Define the properties using @property, which lets the browser know the expected syntax and behavior:

@property –left-fade {
syntax: ““;
inherits: false;
initial-value: 0;
}

@property –right-fade {
syntax: ““;
inherits: false;
initial-value: 0;
}

Next, define the animation itself:

@keyframes scrollfade {
0% {
–left-fade: 0;
}
10%, 100% {
–left-fade: 3rem;
}
0%, 90% {
–right-fade: 3rem;
}
100% {
–right-fade: 0;
}
}

This animation causes the left fade to increase from 0 to 3rem early in the scroll (0–10%), and the right fade to decrease from 3rem to 0 toward the end (90–100%).

Step 3: Combine Everything with scroll-timeline

Now, link the animation to the scroll position using animation-timeline. Update the mask to use the custom properties:

.scrollable {
mask: linear-gradient(
to right,
transparent,
white var(–left-fade),
white calc(100% – var(–right-fade)),
transparent
);
animation: scrollfade linear;
animation-timeline: scroll();
}

This ties the fade animation directly to the scroll progress of the element itself.

Browser Support Note

At the time of writing, not all browsers (notably Safari) support animation-timeline. However, this technique degrades gracefully — the scroll still works, just without the fading effect.

Wrapping Up

This method shows how powerful modern CSS has become. By combining scroll-driven animations with custom property animation, we can create dynamic visual effects without relying on JavaScript. It’s perfect for scrollable tables, carousels, and card layouts — and it works across different backgrounds and content types.

With just a few lines of CSS, we’ve created a polished, responsive visual cue that enhances user experience and accessibility.


Discover more from WIREDGORILLA

Subscribe to get the latest posts sent to your email.

Similar Posts