I want to enable scroll shadows when content exceeds the available width. This I am trying to achieve with pure CSS (no JS). Using a technique I found in various articles, I can achieve my goal with multiple CSS backgrounds and background-attachment.
The below code is working fine if the content is text only. However, in the case of buttons, the shadow backgrounds get displayed behind the buttons. How can I display these shadows above the buttons?
Expected behavior:

Scenario A: enable shadow only at right side, as scroll bar is at extreme left
Scenario B: enable shadows on both right & left side, as scroll bar is somewhere in the middle
Scenario C: enable shadow only at left side, as scroll bar is at extreme right
Example:
/**
* Scrolling shadows by @kizmarh and @leaverou
* Only works in browsers supporting background-attachment: local; & CSS gradients
* Degrades gracefully
*/
html {
background: white;
font: 120% sans-serif;
}
.scrollbox {
overflow: auto;
width: 200px;
max-height: 160px;
margin: 0 auto;
background:
/* Shadow covers */
linear-gradient(white 30%, rgba(255, 255, 255, 0)), linear-gradient(rgba(255, 255, 255, 0), white 70%) 0 100%,
/* Shadows */
radial-gradient(50% 0, farthest-side, rgba(0, 0, 0, .2), rgba(0, 0, 0, 0)), radial-gradient(50% 100%, farthest-side, rgba(0, 0, 0, .2), rgba(0, 0, 0, 0)) 0 100%;
background:
/* Shadow covers */
linear-gradient(white 30%, rgba(255, 255, 255, 0)), linear-gradient(rgba(255, 255, 255, 0), white 70%) 0 100%,
/* Shadows */
radial-gradient(farthest-side at 50% 0, rgba(0, 0, 0, .2), rgba(0, 0, 0, 0)), radial-gradient(farthest-side at 50% 100%, rgba(0, 0, 0, .2), rgba(0, 0, 0, 0)) 0 100%;
background-repeat: no-repeat;
background-color: white;
background-size: 100% 40px, 100% 40px, 100% 14px, 100% 14px;
/* Opera doesn't support this in the shorthand */
background-attachment: local, local, scroll, scroll;
}
<div class="scrollbox">
<ul>
<li>Ah! Scroll below!</li>
<li><button>Button</button></li>
<li><button>Button</button></li>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li><button>Button</button></li>
<li><button>Button</button></li>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
<li>10</li>
<li>The end!</li>
<li>No shadow there.</li>
</ul>
</div>
Interesting question, somewhat inspired by the other answers, here is a horizontally scrolling scrollbox as OP asked for.
html {
height: 100%;
}
body {
display: flex;
align-items: center;
justify-content: center;
height: 100%;
}
.scrollbox {
display: flex;
column-gap: 1rem;
position: relative;
width: 80vw;
overflow-x: auto;
overscroll-behavior: contain;
}
.item {
height: 30vh;
aspect-ratio: 1.41;
background-color: silver;
}
.shadowHider {
position: absolute;
height: 30vh;
width: 1rem;
background-color: white;
z-index: 2;
}
.shadowHider--end {
position: sticky;
margin-left: -2rem;
flex: 0 0 1rem;
left: calc(100% - 1rem);
}
.shadow {
position: sticky;
z-index: 1;
height: 30vh;
flex: 0 0 1rem;
}
.shadow--start {
left: 0;
margin-right: -1.5rem;
background-image: linear-gradient(90deg, #0004, transparent);
}
.shadow--end {
right: 0;
margin-left: -1.5rem;
background-image: linear-gradient(90deg, transparent, #0004);
height: 30vh;
width: 1rem;
left: calc(100% - 2rem);
}
<div class="scrollbox">
<div class="shadowHider shadowHider--start"></div>
<div class="shadow shadow--start"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="shadow shadow--end"></div>
<div class="shadowHider shadowHider--end"></div>
</div>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With