You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为水平滚动容器添加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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 10:39:16