Offcanvas 打开后背景还能滚动,根本原因是 Bootstrap 未成功给 body 添加 modal-open 类,该类负责设置 overflow: hidden 和 padding-right 补偿;必须通过 bootstrap.Offcanvas.getInstance(el).show() 触发,而非手动添加类或硬设 display 样式。

Offcanvas 打开后背景还能滚?检查 modal-open 类有没有加到 body
Bootstrap 5 的 offcanvas 默认就禁用背景滚动,前提是它成功给 body 加了 modal-open 类——这个类会同时设 overflow: hidden 和补偿 padding-right。如果背景还能滚,第一件事是打开开发者工具,看 body 上有没有这个类。
- 别手动
document.body.classList.add('modal-open'):必须由 Bootstrap 自己的 JS 初始化触发,比如用bootstrap.Offcanvas.getInstance(el).show() - 别在 HTML 里直接写
class="show"或硬设style="display: block":绕过 JS 控制流会导致modal-open完全缺失 - 检查有没有全局 CSS 写了
body { overflow: visible !important }:这种声明会直接覆盖modal-open的效果
想彻底禁用点击遮罩 + ESC 关闭?data-bs-backdrop="static" 和 data-bs-keyboard="false" 必须一起用
只设 data-bs-backdrop="static" 不够,用户按 ESC 还是能关掉菜单;只设 data-bs-keyboard="false" 也不行,点遮罩照样关闭。两个属性缺一不可,且值必须是字符串:
-
data-bs-backdrop="static"→ 禁用点击遮罩层关闭 -
data-bs-keyboard="false"→ 禁用 ESC 键关闭(注意不是小写false拼错,也不是布尔值false) - 漏掉
bs-前缀(比如写成data-backdrop)会导致完全失效
桌面常驻 + 移动端折叠?别用 JS 切换同一个 offcanvas,用两套结构分离
试图用 JS 在 desktop 上调用 show()、mobile 上调用 hide() 同一个 offcanvas 容器,极易导致 backdrop 残留、事件绑定错乱或关闭失效。正确做法是用响应式类隔离两套 DOM:
- 桌面导航:普通
<nav>+class="d-none d-lg-block"(桌面显示、移动端隐藏) - 移动端 offcanvas:独立容器,加
class="d-lg-none"(桌面隐藏、移动端显示),并配data-bs-placement="start" - 触发按钮也得分开:桌面用常规链接,移动端用带
data-bs-toggle="offcanvas"的按钮
自定义遮罩颜色或菜单背景时,.offcanvas-backdrop 和 .offcanvas 必须分别处理
遮罩层和菜单主体是两个独立 DOM 元素,CSS 作用域不共享。直接改 .offcanvas 不会影响遮罩,反之亦然:
- 改遮罩色必须针对
.offcanvas-backdrop,且要用!important覆盖 Bootstrap 内联的opacity样式:.offcanvas-backdrop { background-color: rgba(0,0,0,0.7) !important; } - 菜单背景透明化可加
backdrop-filter,但 Safari 需额外加-webkit-backdrop-filter - 千万别碰
.offcanvas.show的transform值——破坏动画队列后,菜单容易卡在半开状态
modal-open 的增删逻辑会被干扰,这时候靠 CSS 强制 overflow 反而更危险。


















