遮罩层必须用 position: fixed 且挂载在 body 下,设 top:0;left:0;width:100vw;height:100vh(iOS 加 -webkit-fill-available),禁用 transform/will-change,用 .offcanvas-backdrop 类并配 data-bs-backdrop="true",背景色调 alpha 值,加 opacity 过渡,展开时锁 body 滚动并设 touch-action: none。

遮罩层必须用 position: fixed,不能用 absolute
侧边栏展开时,遮罩要盖住整个视口且不随滚动偏移——position: absolute 会相对于最近的定位祖先,一旦父容器有 overflow: hidden 或 transform,遮罩就被裁剪或错位;而 position: fixed 始终锚定视口,是唯一可靠选择。
实操要点:
- 遮罩元素必须直接挂载在
下(用 JSinsertAdjacentHTML('beforeend', ...)最稳妥) - CSS 必须写死四方位:
top: 0; left: 0; width: 100vw; height: 100vh; - iOS Safari 对
100vh计算不准,加兜底:height: -webkit-fill-available; - 别给遮罩设
transform或will-change,否则创建新层叠上下文,压不住侧边栏
.offcanvas-backdrop 是 Bootstrap 的标准遮罩类,别手写
Bootstrap 5 的 offcanvas 组件原生生成并管理 .offcanvas-backdrop,手动添加同功能 div 会导致双遮罩、z-index 冲突、iOS 滚动卡顿,甚至点击失效。
正确做法:
立即学习“前端免费学习笔记(深入)”;
- 确保
data-bs-backdrop="true"(默认已启用),不要删掉或重命名.offcanvas-backdrop类 - 调透明度只改背景色:
.offcanvas-backdrop { background-color: rgba(0, 0, 0, 0.4) !important; } - 禁用遮罩?设
data-bs-backdrop="false",而不是把background-color改成transparent(后者仍锁滚动) - 响应式断点要同步:若侧边栏用
offcanvas-lg,遮罩逻辑也得在lg断点后移除,否则小屏展开时大屏遮罩残留
遮罩的“阴影感”来自 rgba() alpha 值,不是 box-shadow
所谓“阴影遮罩”其实是视觉错觉——真正起作用的是半透明黑色背景。加 box-shadow 不仅无效,还会干扰点击穿透行为和过渡动画。
调参建议:
- alpha 值控制压迫感:
rgba(0,0,0,0.5)是平衡点,升到0.65更强,但别超0.7,否则文字看不清 - 入场更自然:加
transition: opacity 0.2s ease-in-out,并在 JS 中切换前先设opacity: 0,再触发重排(如读取offsetWidth),最后设opacity: 1 - 绝对不要用
opacity: 0.5整体调节——它会让遮罩点击区域“变薄”,用户误判是否可点,且子元素也发虚
移动端必须处理 body 滚动锁和 touch-action
iOS Safari 对遮罩最敏感:漏掉任一环节,轻则点击穿透,重则页面冻结无法滚动。
关键补丁:
- 展开侧边栏时,立刻给
body加overflow: hidden;关闭时务必同步移除 - 遮罩层必须加
touch-action: none,否则 iOS 可能跳过 click 直接触发 tap,导致事件穿透到底层 - 如果侧边栏内容区可滚动,其容器需设
overscroll-behavior: contain,防止滑到底部拖拽背景页 - 遮罩层
z-index推荐设为1040(与 Bootstrap 的.modal-backdrop同级),侧边栏至少1030,主内容区必须更低
body 滚动锁没清理干净,或者 touch-action: none 漏写了,这两处一出问题,整个遮罩体验就崩了。


















