bootstrap 5 offcanvas 宽度须用 --bs-offcanvas-width 变量设置,禁用 width/max-width;图标模式需重置 padding 和居中;关闭按钮必须含 data-bs-dismiss="offcanvas";offcanvas 必须为 body 直接子元素。

offcanvas 宽度只能用 CSS 变量改,别碰 width 或 max-width
Bootstrap 5 的 offcanvas 宽度由 CSS 自定义属性 --bs-offcanvas-width 控制,硬写 width: 280px 或 max-width 会破坏动画、遮罩定位和滚动逻辑。尤其是 Safari 下,直接设 width 会导致滑入时抖动或遮罩错位。
正确做法是通过 style 属性或外部样式表覆盖变量:
<div class="offcanvas offcanvas-start" id="sidebar" style="--bs-offcanvas-width: 280px;">
<p>或者用类选择器(推荐):</p>
<pre class="brush:php;toolbar:false;">.offcanvas-sidebar { --bs-offcanvas-width: 280px; }
- 必须加在
.offcanvas元素本身上,父容器或 wrapper 上无效 - 变量值支持
px、rem、vw,但避免用百分比(如80%),它会基于视口而非触发上下文,导致移动端异常 - 如果同时用了
offcanvas-start和offcanvas-end类(错误写法),变量会被忽略
图标模式侧边栏的 padding 和居中必须手动重置
默认 list-group-item 或 nav-link 是为文字设计的:padding: 0.5rem 1rem、line-height: 1.6,塞进小图标后上下空隙过大、视觉松散、点击区域偏小。
图标模式(比如宽度压到 80px)下,必须显式覆盖这些样式:
.sidebar-icon-item { padding: 0.75rem 0; display: flex; align-items: center; justify-content: center; text-align: center; }
- 去掉
line-height,用flex + align-items: center居中更稳定 - 如果用 Font Awesome,务必加
fa-fw类,否则不同图标宽度不一,列表会左右晃动 - 别用
text-lg或h5控制图标大小,混用会导致高度不一致;统一用fs-4(Bootstrap 5.3+)或font-size: 1.25rem
关闭按钮必须带 data-bs-dismiss="offcanvas",不是靠 aria-label
很多开发者以为放个 <button aria-label="Close"></button> 就能关 offcanvas,结果点了没反应——关闭行为完全依赖 data-bs-dismiss="offcanvas" 这个触发器,JS 内部靠它识别并销毁实例。
标准写法:
<button type="button" class="btn-close" data-bs-dismiss="offcanvas"></button>
- 不能只写
class="btn-close"而漏掉data-bs-dismiss - 手写 × 图标(
×)或用onclick="..."会丢失键盘支持(ESC 键、Tab 焦点跳转) - 如果想禁用背景点击关闭,得在 JS 初始化时传
{ backdrop: false },而不是删掉data-bs-dismiss
offcanvas 必须挂载在 直接子级,嵌套在 <main></main> 或 <div class="container"> 里会失效
<p>这是最常被忽略的硬约束:Bootstrap 5 的 offcanvas 依赖 <code>document.body 做事件委托、遮罩层插入和 ESC 键监听。一旦把它写在局部容器里,90% 会出现点击遮罩不关闭、ESC 失效、滚动错位等问题。
错误写法:
<main><div class="offcanvas offcanvas-start"></div></main>
正确写法(与 <header></header>、<main></main> 并列):
<header>...</header><main>...</main><div class="offcanvas offcanvas-start" id="sidebar"></div>
- Vue/React 中需用
Teleport(Vue)或createPortal(React)把 offcanvas 节点挂到document.body - 动态加载 offcanvas HTML 后再调
show(),必须确保 DOM 已就绪,否则new bootstrap.Offcanvas(...)会报错 - id 不匹配(比如
data-bs-target="#nav"对应的id是nav-menu)也会导致完全无响应











