必须将 --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;">- 外部样式:
.offcanvas-sidebar { --bs-offcanvas-width: 280px; },且该类必须加在<div class="offcanvas">元素自身上
禁用百分比单位(如 80%),它基于视口而非触发上下文,移动端容易错位。
--bs-offcanvas-width 必须设在 <div class="offcanvas"> 本身,且是 <body> 直接子元素
很多人把 offcanvas 套在 <main>、<div class="container"> 或自定义 wrapper 里,再给外层加变量——JS 初始化时根本读不到,document.getElementById() 返回 null,控制台报 Cannot read properties of null 就是这个原因。
立即学习“前端免费学习笔记(深入)”;
必须确保:
-
<div class="offcanvas">是<body>的直接子节点(不能嵌套) - 变量写在该节点上,不是父容器、不是 wrapper、不是 class="sidebar" 这类自定义类
- 同时加
offcanvas-start和offcanvas-end会导致变量被忽略
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 会让小图标上下空隙过大、点击区域偏小、视觉松散。
需手动覆盖:
- 用
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
关闭按钮失效?检查 data-bs-dismiss="offcanvas" 是否在正确位置
很多开发者以为放个 <button aria-label="Close"></button> 就能关 offcanvas,结果点了没反应——关闭行为完全由 data-bs-dismiss="offcanvas" 触发,JS 内部靠它识别并销毁实例。
必须满足:
- 该属性写在按钮上,不能靠 JS 手动绑定 click
- 按钮必须位于 offcanvas 内部(不能放在外部再操作 DOM)
- 标准写法:
<button type="button" class="btn-close" data-bs-dismiss="offcanvas"></button> - 手写 × 或用
onclick会丢失键盘关闭支持(ESC、Tab 焦点管理失效)
最易被忽略的是:offcanvas 必须是 <body> 直接子元素 + --bs-offcanvas-width 在正确节点 + data-bs-dismiss 在内部按钮上——三者缺一,宽度就只是“看起来改了”,实际交互和动画早已崩坏。


















