Pure CSS Scroll Shadows (Vertical + Horizontal)

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 2021.10.06: The workaround listed below no longer works with iOS15 😭

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;
  }
}
Did this help you out? Like what you see?
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!

☕️ Buy me a Coffee (€3)

To stay in the loop you can follow @bramus or follow @bramusblog on Twitter.

About the author

Bramus is a Freelance Web Developer from Belgium. From the moment he discovered view-source at the age of 14 (way back in 1997), he fell in love with the web and has been tinkering with it ever since (more …)

Join the Conversation

1 Comment

Leave a comment

Leave a Reply to can Cancel reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.