必须保留navbar-expand-*类,否则移动端无汉堡菜单且折叠逻辑失效;其后缀决定展开临界点(如md对应≥768px展开),小于此值自动折叠。

直接用 .navbar-expand-* 控制展开断点,别删它
很多人想“转为垂直”,第一反应是删掉 .navbar-expand-sm 这类类——结果菜单在所有尺寸下都竖着堆叠,且汉堡按钮永远不出现。这不是垂直折叠菜单,只是个失效的 navbar。真正可控的做法是保留 .navbar-expand-md(或你选的断点),让中屏及以上水平展开,小屏自动折叠成 hamburger。
常见错误现象:Uncaught TypeError: Cannot read properties of null (reading 'classList'),多因删了 .navbar-expand-* 后,.navbar-collapse 容器没被 Bootstrap JS 正确识别为可折叠目标。
- 必须保留
.navbar-expand-*,否则.navbar-toggler不会绑定 collapse 行为 - 移动端默认折叠,桌面端自动水平展开,这是 Bootstrap 5 的预期行为,不是 bug
- 若需“桌面端也垂直”,请改用
.nav-pills.flex-column+ 栅格布局,而非硬改 navbar
给 .navbar-collapse 加 data-bs-parent 防止多级菜单误收
垂直折叠菜单常带二级项(比如“产品 → Web / App”),但 Bootstrap 5 默认 collapse 不支持嵌套收起逻辑。点击一级项时,整个 .navbar-collapse 可能意外收起,或二级菜单打不开。
解决办法不是写一堆 event.stopPropagation(),而是利用 collapse 的 data-bs-parent 属性隔离作用域:
立即学习“前端免费学习笔记(深入)”;
- 把每个可折叠的二级菜单(如
<div class="collapse">)包进独立<li class="nav-item"> - 给该
div.collapse加data-bs-parent="#navbarNav",其中#navbarNav是外层.navbar-collapse的 ID - 这样二级 collapse 只响应自己父级的展开/收起,不会干扰顶层导航栏状态
用 offcanvas 替代 collapse 实现真垂直侧边栏
如果目标是“左侧固定垂直菜单,点击汉堡图标滑出”,.collapse 不够用——它只缩 height,不移出视口,键盘焦点、屏幕阅读器、滚动表现全都不达标。
Bootstrap 5 的 offcanvas 才是为此设计的:DOM 移出流、自带遮罩、支持 aria-hidden 同步、原生支持 ESC 关闭和 backdrop 点击关闭。
- 结构必须是:
<div class="offcanvas offcanvas-start d-lg-none" id="offcanvasNav">包住整个垂直菜单 - 触发按钮加
data-bs-toggle="offcanvas"和data-bs-target="#offcanvasNav" - 桌面端用
d-none d-lg-block显示常规.nav-pills.flex-column,移动端用 offcanvas,两套 DOM 分离 - 别用
d-none d-sm-block隐藏侧边栏——它只是视觉隐藏,仍占位、可聚焦、破坏可访问性
垂直菜单宽度抖动?用 min-width + flex-shrink-0 锁定
垂直菜单从 collapse 展开后,文字换行、图标错位、整体宽度忽大忽小,问题往往不在 JS,而在 CSS 没锁住容器行为。
.navbar-collapse 默认是 flex item,受父容器 .navbar 的 flex-wrap 和 flex-shrink 影响,尤其在窄屏下会被压缩变形。
- 给
.navbar-collapse加flex-shrink-0,禁止它被压缩 - 加
min-width: 220px(或你所需值),防止内容撑不开时塌陷 - 若用
offcanvas,直接在.offcanvas-body上设min-width更稳妥 - 避免对
.nav-link单独设width,应统一控制父容器宽度
最易被忽略的一点:垂直折叠菜单不是靠“改一个类”实现的,而是由结构(offcanvas vs collapse)、作用域(data-bs-parent)、可访问性(aria-hidden、focus management)三者共同决定的。CSS 只负责视觉表达,JS 和语义结构才是折叠行为的真正开关。


















