滚动容器两侧没阴影是因为box-shadow是静态的,真滚动阴影需用mask-image渐变遮罩配合伪元素实现;overflow:overlay已废弃,老浏览器需JS监听scrollLeft动态控制类名。

滚动容器两侧为什么没阴影?
直接用 box-shadow 给容器加阴影,滚动时阴影不会随内容移动,看起来像“贴死”在容器边缘——这不是滚动阴影,是静态边框假象。真滚动阴影必须让阴影跟随可视区域边界动态出现/消失,核心靠「遮罩层 + 溢出裁剪」配合实现。
用 mask-image 实现左右滚动阴影(现代方案)
这是目前最干净、无需 JS、兼容 Chrome 112+ / Safari 16.4+ / Firefox 119+ 的方式。关键不是加 shadow,而是用渐变遮罩“盖住”溢出部分,只让中间内容可见,再叠加一层固定位置的阴影层作视觉提示。
实操要点:
- 容器设
overflow-x: auto和scrollbar-width: none(Firefox)或::-webkit-scrollbar { display: none } - 用伪元素
::before覆盖在容器顶部,设mask-image: linear-gradient(90deg, black 0%, transparent 20%, transparent 80%, black 100%) - 该伪元素本身带
box-shadow: 0 0 12px rgba(0,0,0,0.15),但因 mask 存在,只在左右 20% 区域透出阴影 - 注意:mask 的渐变方向必须和滚动方向一致(横向滚动用
90deg),百分比数值决定阴影显示宽度,太窄会看不见,太宽会盖住内容
overflow: overlay 不起作用?别用它
overflow: overlay 是旧版 WebKit 私有属性,早已被废弃,Chrome 从 98 版本起完全移除,Safari 也不再支持。试图靠它“让滚动条不占位从而方便加阴影”只会白忙——它既不触发阴影渲染逻辑,也不影响遮罩行为。
常见错误现象:overflow: overlay 写了但滚动条依然占位、阴影错位、甚至整个容器无法滚动。
替代思路:
- 用
overflow: scroll+scrollbar-gutter: stable both-edges(稳定滚动条预留空间,避免布局抖动) - 或者彻底隐藏滚动条,靠阴影本身作为滚动提示,此时更需确保
mask-image渐变范围略大于实际阴影扩散范围(比如用 15%–85% 替代 20%–80%)
需要兼容老浏览器?用 JS 监听 scrollLeft 动态切 class
IE11、旧版 Edge 或 Android UC 浏览器不支持 mask-image,只能退化为 JS 方案:监听容器 scrollLeft 值,根据是否在起点/终点动态添加 shadow-left 或 shadow-right 类,再用 CSS 控制对应侧的 box-shadow 显隐。
容易踩的坑:
- 别在
scroll事件里直接操作 DOM 样式——触发太频繁,卡顿明显;改用requestIdleCallback或节流(如 60ms 一次) -
scrollLeft === 0判断起点没问题,但终点得用scrollLeft >= scrollWidth - clientWidth,注意浮点误差,建议加Math.abs(...) 容差 - 阴影 class 最好只控制
box-shadow和pointer-events: none(避免遮挡点击),不要动opacity或transform,否则影响性能
CSS mask 的渐变停靠点位置、JS 中 scrollWidth 计算时机、以及阴影扩散半径与容器 padding 的关系——这三处稍调就容易失效,动手前先在小容器里验证边界情况。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











