Bootstrap 5.2+ 才正式稳定支持 offcanvas 组件,5.0–5.1 版本为实验性功能,存在 DOM 结构不稳、backdrop 残留、缺失 data-bs-scroll 等问题;必须手动编写 HTML 结构并置于 body 直接子级,配合 data-bs-toggle="offcanvas" 和正确 ID 触发。

Offcanvas 组件在 Bootstrap 5.2+ 才正式稳定支持
Bootstrap 5.0 和 5.1 的 offcanvas 是实验性功能,DOM 结构、JS 行为和 CSS 类名都不稳定;升级到 5.2.0+ 后才移除 .offcanvas-backdrop 的强制插入逻辑、修复多次 toggle 时 backdrop 残留、支持 data-bs-scroll 等关键特性。如果你用的是旧版本,data-bs-toggle="offcanvas" 可能根本没反应,或者关不掉——先检查 bootstrap.min.js 版本号。
必须手动写 HTML 结构,不能只靠 data 属性触发
Bootstrap 的 Offcanvas 不像 Modal 那样允许纯按钮触发后自动生成 DOM;它要求你提前把 <div class="offcanvas"> 放在 <code> 下(不能嵌套在其他组件内部),否则 JS 初始化会找不到目标或定位错乱。常见错误包括:
- 把
<div class="offcanvas"> 写在 <code><header></header>或<main></main>里,导致 backdrop 覆盖范围异常 - 漏写
tabindex="-1",键盘无法聚焦关闭 - 没加
id,data-bs-target就失效
正确结构示例:
<button class="btn btn-primary" type="button" data-bs-toggle="offcanvas" data-bs-target="#myOffcanvas">
Open Offcanvas
</button>
<div class="offcanvas offcanvas-start" tabindex="-1" id="myOffcanvas" aria-labelledby="myOffcanvasLabel">
<div class="offcanvas-header">
<h5 class="offcanvas-title" id="myOffcanvasLabel">Offcanvas</h5>
<button type="button" class="btn-close text-reset" data-bs-dismiss="offcanvas" aria-label="Close"></button>
</div>
<div class="offcanvas-body">
Content here
</div>
</div>
offcanvas-start / offcanvas-end 控制方向,但移动端默认全屏
方向类名决定侧边栏从哪边滑入:offcanvas-start(左)、offcanvas-end(右)、offcanvas-top(上)、offcanvas-bottom(下)。但注意:在宽度 (即 <code>md 断点以下)时,所有 Offcanvas 默认表现为「全高/全宽覆盖式」,且 backdrop 会强制显示;这是 Bootstrap 响应式设计的硬编码逻辑,无法用 CSS 覆盖 @media 规则绕过。如果需要小屏也保持窄幅抽屉效果,得自己重写 .offcanvas.show 的 transform 和 width。
关闭后焦点不会自动回退,需手动处理可访问性
点击关闭按钮或 backdrop 关闭 Offcanvas 后,焦点会丢失,对屏幕阅读器用户不友好。Bootstrap 不自动管理焦点回退(不像 Modal 那样有 returnFocus 选项)。解决方法是监听 hidden.bs.offcanvas 事件,并显式调用 triggerEl.focus():
const myOffcanvas = document.getElementById('myOffcanvas')
myOffcanvas.addEventListener('hidden.bs.offcanvas', event => {
const triggerEl = document.querySelector('[data-bs-target="#myOffcanvas"]')
if (triggerEl) triggerEl.focus()
})
这个细节容易被忽略,尤其当 Offcanvas 由多个不同按钮触发时,得确保每次都能拿到正确的触发元素。


















