bootstrap 5 默认禁用多级下拉菜单,因移动优先设计导致子菜单无事件绑定、css 层级错乱及点击即收起;需用自定义 js 阻止冒泡并接管展开逻辑,配合响应式 css 实现兼容二级菜单。

Bootstrap 原生不支持多级下拉菜单(dropdown-menu 嵌套在另一个 dropdown-menu 内时,子菜单默认不显示、无 hover/click 逻辑、移动端点击即收起),强行用 CSS 展开会导致触控失效或响应式断裂。
为什么 Bootstrap 5 默认禁用多级菜单
核心原因是移动优先设计:原生 dropdown 组件只监听一级 data-bs-toggle="dropdown",且 Dropdown JavaScript 插件未递归绑定子菜单事件;CSS 中 .dropdown-menu 的 display: none 在父级未激活时无法被子项覆盖,同时 position: absolute 层级叠加易错乱。
- 移动端点击任意下拉项后,整个
dropdown立即隐藏(包括正在展开的子菜单) - 悬停(
:hover)在触摸设备上无意义,且 Bootstrap 5 已移除对hover的 JS 支持 -
dropdown-menu子元素若再加dropdown类,其data-bs-toggle不会被初始化
用纯 CSS + 少量 JS 实现可点击的二级菜单(兼容 BS5)
不依赖第三方插件,仅扩展原生行为:让二级菜单在点击父项时展开,并在点击空白处或其它菜单项时收起。关键在于接管点击逻辑,避免触发 Bootstrap 默认的关闭链。
- 给二级触发项(如
<a class="dropdown-item">Services</a>)添加自定义类dropdown-submenu-toggle - 对应二级菜单使用
<ul class="dropdown-menu dropdown-submenu"></ul>,并初始设为display: none - 用 JS 监听
click,阻止事件冒泡到上级dropdown的关闭逻辑:document.addEventListener('click', function(e) { if (e.target.matches('.dropdown-submenu-toggle')) { e.preventDefault(); e.stopPropagation(); // 关键:防止触发父级 dropdown hide const submenu = e.target.nextElementSibling; if (submenu && submenu.classList.contains('dropdown-submenu')) { submenu.classList.toggle('show'); } } else if (!e.target.closest('.dropdown-submenu, .dropdown-submenu-toggle')) { document.querySelectorAll('.dropdown-submenu.show').forEach(el => el.classList.remove('show')); } }); - CSS 补充定位(避免子菜单被裁剪):
.dropdown-submenu { position: absolute; top: 0; left: 100%; margin-top: 0; margin-left: 0; } .dropdown-submenu.show { display: block; } @media (max-width: 991.98px) { .dropdown-submenu, .dropdown-submenu.show { position: static; display: none; } .dropdown-submenu.show { display: block; } }
移动端适配要点:避免“点开即关”陷阱
原生 dropdown 在移动端点击任意项都会关闭整个菜单,这是由 Dropdown.hide() 的全局监听导致的。你写的二级菜单必须绕过它,否则每次点二级标题就收起整个导航栏。
- 不要给二级菜单项加
data-bs-toggle="dropdown"—— 这会注册额外的关闭监听器 - 确保子菜单
<ul></ul>不是.dropdown的直接子节点(即不能是<div class="dropdown"><ul class="dropdown-menu">...</ul></div>的嵌套结构),否则Dropdown实例会错误地将其纳入管理 - 在小屏下(
md断点以下),建议将二级菜单改为「点击展开/收起」的垂直折叠式,而非右向弹出,更符合触摸操作直觉 - 如果使用
navbar-expand-lg,注意@media (min-width: 992px)才启用横向二级菜单,小屏统一用垂直手风琴逻辑
真正难的不是写两层 ul 嵌套,而是让 Bootstrap 不“插手”你的二级逻辑 —— 它的 JS 会默默监听所有带 data-bs-toggle 的元素并统一调度,一旦你没隔离好作用域,菜单就会在你最意想不到的时候突然消失。











