仅靠 backdrop-filter 无法阻止背景滚动,必须在遮罩容器(如 .overlay 或 dialog)上设置 overscroll-behavior: contain 并确保其可滚动;同时需配合 body overflow: hidden 等措施防其他滚动干扰。
overscroll-behavior 将其锁定先说结论:只使用 backdrop-filter: blur() 制作毛玻璃遮罩,并不能阻止后方页面滚动;还必须配合 overscroll-behavior: contain(或 none)并将其应用到遮罩容器本身,才能真正锁定背景滚动。否则,当用户在遮罩内滚动到底后继续拖动,就会带动后方页面滚动,也就是出现“滚动穿透”,使体验产生割裂。
overscroll-behavior 应该设置在哪个元素上?答案是遮罩容器,而不是弹窗内容一种常见错误,是将 overscroll-behavior 设置在弹窗内部的 .modal-content 或滚动区域上,这样不会生效。它必须设置在能够触发 overscroll 的可滚动容器本身,也就是毛玻璃遮罩层,通常为全屏 div.overlay 或 dialog 元素)。
典型结构可以这样组织:
<div class="overlay" style="overscroll-behavior: contain;"> <div class="glass-pane" style="backdrop-filter: blur(12px);"> <div class="modal-content">...</div> </div></div>
.overlay 必须设置 overflow: auto 或 scroll(否则容器不具备滚动能力,overscroll-behavior 也就不会生效).glass-pane 仅用于呈现毛玻璃视觉效果,不承担滚动控制<dialog>,需要留意其默认 overscroll-behavior 为 auto,仍然要明确设置成 contain
contain 而非 none?overscroll-behavior: none 会彻底关闭 overscroll 效果,包括 iOS 的弹性回弹和 Android 的滚动溢出光晕;而 contain 只会阻断向父级传播,同时保留当前容器自身的 overscroll 行为,因此更符合遮罩的交互直觉。
立即学习“前端免费学习笔记(深入)”;
none 在某些安卓 WebView 中,它可能意外阻断 touchmove 事件,从而造成拖拽卡顿contain 使用起来更安全overscroll-behavior 它处理的是“滚动穿透”,但遮罩启用后,后方页面仍可能由于焦点切换、键盘唤起,或 JS 主动调用 scrollTo 而发生跳动,因此必须一并处理:
<body> 添加 overflow: hidden(注意保存原始 scrollTop,并在关闭遮罩时恢复)scrollIntoView ,可以给遮罩中所有可聚焦元素添加 scroll-margin: 0
overscroll-behavior,需要降级为使用 touchmove + preventDefault() 拦截,仅面向 iOS毛玻璃与滚动锁定彼此独立:前者负责视觉,后者控制行为。任何一项没有处理完整,用户滑动手指时都会暴露问题。