Pure
Structure

Scroll shadows with animation-timeline

Scroll shadows are a good hint to users that an element can be scrolled by overlaying shadows on its edges. The table and code elements are prime candidates as their content usually needs to be scrolled horizontally on small screens. There is a CSS based method using background-image from this article by Lea Verou. However with animation-timeline there is now a simpler, more flexible way to achieve this.

This implementation was inspired by Scroll shadows with animation-timeline by Dave Rupert. I have adjusted it to include a subtle shadow in the middle of the scroll, background colours in the scrollable element and a fallback for animation-timeline (Chrome 115+ at time of writing).

The demo includes the full code with comments needed for a table, a table with a sticky column and a code element. The essential styles needed are below the demo.

Demo

See the Pen Scroll Shadows with animation-timeline by Nigel O Toole (@nigelotoole) on CodePen.

Essential Styles

Add overflow, animation-timeline and an animation of inset box-shadows to the element. A large shadow on the right is visible when the element is overflowing, as it is scrolled the right shadow is reduced and a small left shadow is added. Once the full width has been scrolled the right shadow is removed and the left shadow is increased.

.scroll-shadow-inline {
  --shadow-color: rgb(0 0 0 / .2);
  --shadow-size: 8px;
  --shadow-spread: calc(var(--shadow-size) * -.5);
   
  overflow-x: auto;
  animation: scroll-shadow-inset linear;
  scroll-timeline: --scroll-shadow-timeline inline;
  animation-timeline: --scroll-shadow-timeline;
}
 
@keyframes scroll-shadow-inset {
  from {
    box-shadow: 
    inset calc(var(--shadow-size) * -2) 0 var(--shadow-size) var(--shadow-spread) var(--shadow-color), 
    inset calc(var(--shadow-size) * 0) 0 var(--shadow-size) var(--shadow-spread) var(--shadow-color);
  }  
  10%, 90% {
    box-shadow: 
    inset calc(var(--shadow-size) * -1) 0 var(--shadow-size) var(--shadow-spread) var(--shadow-color), 
    inset calc(var(--shadow-size) * 1) 0 var(--shadow-size) var(--shadow-spread) var(--shadow-color);
  }
  to {
    box-shadow: 
    inset calc(var(--shadow-size) * 0) 0 var(--shadow-size) var(--shadow-spread) var(--shadow-color), 
    inset calc(var(--shadow-size) * 2) 0 var(--shadow-size) var(--shadow-spread) var(--shadow-color);
  }
}