如何为水平滚动容器添加CSS滚动阴影效果?
水平滚动容器边缘渐变阴影修复方案
问题描述
参考滚动阴影方案修改后适配水平滚动容器,目标实现:
- 容器边缘添加
linear-gradient渐变阴影 - 滚动到最左侧时左阴影隐藏,最右侧时右阴影隐藏
- 中间位置时两侧阴影同时显示
修改后出现问题:滚动时渐变位置固定,仅显示红色渐变,未达到预期效果。
修复思路
问题核心是多背景的background-attachment顺序与水平滚动逻辑不匹配,需调整以下几点:
- 修正
background-attachment对应关系:让遮挡用渐变使用scroll(固定在容器视口),跟随内容的渐变使用local(跟随滚动内容) - 优化渐变颜色过渡:将渐变终点改为透明色,与容器背景自然融合
- 添加交互兼容性:伪元素设置
pointer-events: none,避免遮挡容器内元素的点击事件
修改后的完整代码
HTML
<button id="backwards">Back</button> <button id="forwards">Forwards</button> <div class="boxes-container"> <div class="boxes"> <!-- box 1 --> <div class="box"> <div class="img-container"> <img src="https://a0.muscache.com/pictures/b6005f78-45e6-403a-bc1d-3351ae83d149.jpg" alt=""> </div> <h6>Why host on Airbnb?</h6> <p>Hosts reveal what they love about sharing their space on Airbnb.</p> </div> <!-- box 2 --> <div class="box"> <div class="img-container"> <img src="https://a0.muscache.com/pictures/9ac19f4a-a59c-47f9-8223-09120b52cd2d.jpg" alt=""> </div> <h6>How to get started on Airbnb</h6> <p>From creating your listing to prepping your space, learn how to start hosting.</p> </div> <!-- box 3 --> <div class="box"> <div class="img-container"> <img src="https://a0.muscache.com/pictures/4d0cc0ed-ad85-4efd-b98e-386d22ab195a.jpg" alt=""> </div> <h6>How to earn money on Airbnb</h6> <p>Here's what every Host needs to know about pricing and payouts.</p> </div> <!-- box 4 --> <div class="box"> <div class="img-container"> <img src="https://a0.muscache.com/pictures/4efaca33-ca90-4d94-a79b-381cf0179355.jpg" alt=""> </div> <h6>Designing your space</h6> <p>Designing your space for guests can be a quick way to boost your bookings.</p> </div> <!-- box 5 --> <div class="box" id="last-box"> <div class="img-container"> <img src="https://a0.muscache.com/pictures/3cea79b0-79c3-4604-8fd9-7ef5cee4aa42.jpg" alt=""> </div> <h6>Secrets from a seasoned Superhost</h6> <p>Superhost Nikki shares her tips, from setting up to standing out.</p> </div> </div> </div>
CSS
.boxes-container { margin-top: 2rem; width: 100%; position: relative; } .boxes { display: flex; overflow-x: scroll; -ms-overflow-style: none; scrollbar-width: none; scroll-behavior: smooth; position: relative; z-index: 1; /* 确保内容在伪元素上层 */ } .boxes::after { content: ""; position: absolute; top: 0; bottom: 0; right: 0; left: 0; pointer-events: none; /* 不遮挡内容交互 */ /* 顺序:遮挡左、遮挡右、显示左、显示右 */ background: linear-gradient(90deg, white, transparent) left/100px 100% no-repeat scroll, linear-gradient(90deg, transparent, white) right/100px 100% no-repeat scroll, linear-gradient(90deg, rgba(0,0,0,0.2) 30%, transparent) left/80px 100% no-repeat local, linear-gradient(90deg, transparent, rgba(0,0,0,0.2) 70%) right/80px 100% no-repeat local; /* 对应四个背景的attachment:scroll scroll local local */ background-attachment: scroll scroll local local; } .boxes::-webkit-scrollbar { display: none; } .boxes .box { display: flex; justify-content: center; align-items: center; flex-direction: column; align-items: flex-start; gap: 1rem; width: 332px; max-width: 332px; cursor: pointer; margin-right: 2rem; } .boxes .box#last-box { padding-right: 2rem; } .boxes .box .img-container img { width: 322px; max-width: 322px; height: 200px; -o-object-fit: cover; object-fit: cover; border-radius: 10px; } .boxes .box h6 { font-size: 18px; } .boxes .box p { font-size: 14.5px; font-weight: lighter; letter-spacing: 0.1px; }
JavaScript
const boxesView = document.querySelector('.boxes') const boxes = document.querySelectorAll('.box') // btns const forwardBtn = document.querySelector('#forwards') const backBtn = document.querySelector('#backwards') boxSize = boxes[0].clientWidth forwardBtn.addEventListener('click', () => { boxesView.scrollBy(boxSize, 0) }) backBtn.addEventListener('click', () => { boxesView.scrollBy(-boxSize, 0) })
原理说明
scroll类型的渐变:固定在容器的视口边缘,用来遮挡local类型的渐变——当滚动到最左侧时,左方的scroll渐变(白色)会完全覆盖local的阴影渐变,实现隐藏效果;同理右侧滚动到底时也是如此。local类型的渐变:跟随容器内的滚动内容移动,始终出现在内容的边缘,当内容没有滚动到边缘时,scroll渐变不会完全遮挡它,就会显示出阴影效果。
内容的提问来源于stack exchange,提问作者tices
相关产品推荐
相关产品推荐

