必须将 --bs-offcanvas-width 设在 body 直接子级的 offcanvas 元素上,配合 data-bs-dismiss="offcanvas" 按钮置于其内部,否则动画、遮罩、关闭均失效。

必须用 --bs-offcanvas-width 变量,别碰 width 或 max-width
Bootstrap 5 的 offcanvas 动画、遮罩定位、滚动锁逻辑全依赖 --bs-offcanvas-width 这个 CSS 自定义属性。硬写 width: 280px 或 max-width: 300px 看似生效,实则会破坏 transform 基线计算——Safari 下滑入抖动、遮罩只盖半屏、ESC 关闭失效都是典型表现。
正确做法只有两种:
<div class="offcanvas offcanvas-start" style="--bs-offcanvas-width: 280px;"> <li>外部样式:<code>.offcanvas-sidebar { --bs-offcanvas-width: 280px; },且该类必须加在<div class="offcanvas"> 元素自身上 <p>禁用百分比单位(如 <code>80%),它基于视口而非触发上下文,移动端容易错位。--bs-offcanvas-width必须设在<div class="offcanvas"> 本身,且是 <code>直接子元素很多人把 offcanvas 套在
<main></main>、<div class="container"> 或自定义 wrapper 里,再给外层加变量——JS 初始化时根本读不到,<code>document.getElementById()返回 null,控制台报Cannot read properties of null就是这个原因。必须确保:
<div class="offcanvas"> 是 <code>的直接子节点(不能嵌套)- 变量写在该节点上,不是父容器、不是 wrapper、不是 class="sidebar" 这类自定义类
- 同时加
offcanvas-start和offcanvas-end会导致变量被忽略 - 用
d-flex align-items-center justify-content-center替代line-height居中,更稳定 - 显式写
padding: 0.75rem 0,去掉左右内边距 - Font Awesome 图标务必加
fa-fw类,防宽度不一导致列表晃动 - 统一用
fs-4或font-size: 1.25rem控大小,别混用text-lg或h5 - 该属性写在按钮上,不能靠 JS 手动绑定 click
- 按钮必须位于 offcanvas 内部(不能放在外部再操作 DOM)
- 标准写法:
<button type="button" class="btn-close" data-bs-dismiss="offcanvas"></button> - 手写 × 或用
onclick会丢失键盘关闭支持(ESC、Tab 焦点管理失效)
Vue/React 中没用
Teleport或createPortal挂到document.body,也会导致 backdrop 插入错位、滚动锁不释放。图标模式(窄宽度)下必须重置 padding 和居中逻辑
当把
--bs-offcanvas-width压到80px这类图标模式时,原生的list-group-item或nav-link样式完全不适用:默认padding: 0.5rem 1rem和line-height: 1.6会让小图标上下空隙过大、点击区域偏小、视觉松散。需手动覆盖:
关闭按钮失效?检查
data-bs-dismiss="offcanvas"是否在正确位置很多开发者以为放个
<button aria-label="Close"></button>就能关 offcanvas,结果点了没反应——关闭行为完全由data-bs-dismiss="offcanvas"触发,JS 内部靠它识别并销毁实例。必须满足:
最易被忽略的是:offcanvas 必须是
直接子元素 +--bs-offcanvas-width在正确节点 +data-bs-dismiss在内部按钮上——三者缺一,宽度就只是“看起来改了”,实际交互和动画早已崩坏。











