A long time ago (2012!), Lea Verou shared a way on how to add scrolling shadows to containers that needs scrolling. Using those shadows in a scroll container is a great UX thing, as they visually tell the user that the content is scrollable.
Her code however, only worked with containers that scroll vertically. Based upon Lea’s code I created a version that also plays nice with horizontal scroll containers.
Whilst I was at it, I also introduced CSS Custom Properties, as they allow easy theming. Using the “CSS Variables” --background-color
, --shadow-color
, and --shadow-size
you can configure the result.
Hope you like it 🙂
# 🐛🍏 A note on MobileSafari (iOS)
Update 2022.07.05: The workaround listed below was necessary for iOS versions predating iOS 15. The fix is no longer needed as of iOS 15.4. Versions 15.0 – 15.4 had a regression that prevented this fix from working, so those specific versions do not support pure CSS Scroll Shadows.
Out of the box this technique unfortunately does not play that nice on iOS: MobileSafari does not seem to re-render the backgrounds during scroll. I did notice however that it will correctly re-render after manually zooming in and out on the page. This is detailed in Webkit Bug 181048.
In said bug report a solution to the problem is mentioned:
I’ve discovered that updating a CSS variable on a
-webkit-overflow-scrolling: touch;
element when it’s scrolled causes it to repaint correctly.
With a little bit of JavaScript we can trigger exactly this:
// Fix for Mobile Safari that doesn't correctly re-render backgrounds during scroll
// @ref https://bugs.webkit.org/show_bug.cgi?id=181048
if (CSS.supports("-webkit-overflow-scrolling: touch")) {
document.querySelectorAll(".scrollcontainer").forEach((scroller) => {
scroller.addEventListener("scroll", () => {
scroller.style.setProperty("--force-paint", Date.now());
});
});
}
It’s also possible to force repaints by attaching an animation to the .scrollcontainer
. Even a dummy (empty) animation will do.
/*Fix for Mobile Safari that doesn't correctly re-render backgrounds during scroll */
@supports (-webkit-overflow-scrolling: touch) {
@keyframes dummy {
}
.scrollcontainer {
animation: 1s dummy linear infinite;
}
}
Thank me with a coffee.
I don\'t do this for profit but a small one-time donation would surely put a smile on my face. Thanks!
To stay in the loop you can follow @bramus or follow @bramusblog on Twitter.
Did you try with the image at the bottom?
How do you prevent the scrollbars from overlapping the shadows? I have tried every property I can think of, even some experimental ones. Am I missing something simple?