Bootstrap 5 官方移除响应式多级下拉菜单支持,二级及以上菜单默认隐藏且无交互逻辑;需通过 CSS 修复定位与显隐、JS 实现点击控制及键盘导航,并手动处理移动端和无障碍适配。

Bootstrap 5 官方不支持响应式多级下拉菜单——不是你写错了,是框架主动移除的。所有嵌套在 .dropdown-menu 内的二级、三级菜单默认被设为 display: none,且无 hover、click 或键盘触发逻辑。强行堆 data-bs-toggle="dropdown" 没用,JS 不初始化子菜单,CSS 不显隐,移动端一点就收。
为什么 .dropdown-menu .dropdown-menu 始终不显示
常见现象:HTML 结构看着对,鼠标悬停或点击后子菜单就是不出来。根本原因有三个:
- 父级
.dropdown-item缺少position: relative,导致子.dropdown-menu的left: 100%相对于body定位,直接飞出视口 - Bootstrap 5 默认给
.dropdown-menu .dropdown-menu加了opacity: 0和visibility: hidden,而你写的display: block被覆盖 -
.dropdown-menu的初始display: none未被清除,浏览器渲染时仍以它为准
纯 CSS 实现二级悬停(仅限桌面)
这是最轻量的方案,适合静态导航,但不兼容触摸设备和屏幕阅读器。关键不是加样式,而是解除定位错乱和显隐冲突:
- 必须给父级
.dropdown-item加position: relative -
.dropdown-menu .dropdown-menu设为position: absolute; top: 0; left: 100%; display: none; - 用
.dropdown-item:hover > .dropdown-menu触发display: block,不能只写.dropdown:hover .dropdown-menu(会一次性展开所有层级) - 加
z-index: 1001,确保二级菜单不被兄弟菜单遮盖 - 必须包裹二级菜单容器为
.dropdown-submenu,否则overflow: hidden会切掉内容
JS 主导实现可点击的二级菜单(兼顾移动端)
纯 :hover 在触屏和键盘导航中失效。推荐监听 click 并手动控制 show/hide,同时阻止冒泡避免一级菜单意外关闭:
- 给二级触发项加自定义类如
dropdown-submenu-toggle - 对应二级菜单用
<ul class="dropdown-menu dropdown-submenu">,初始display: none - 监听
click事件,调用e.stopPropagation()阻止事件冒泡到上级.dropdown - 用
submenu.classList.toggle('show')控制显隐,而非依赖 Bootstrap 的show类自动绑定 - 点击空白处时,遍历并清除所有
.dropdown-submenu.show
响应式断裂点必须手动接管
Bootstrap 的 dropend、dropstart 只作用于一级菜单,对二级及以上无效。小屏下硬塞横向展开会导致溢出或被裁剪:
- 用
@media (max-width: 992px)把二级菜单降级为垂直展开:top: 100%; left: 0; - 三级菜单在小屏应完全禁用或转为折叠面板(
accordion),不要强求“三级联动” - 所有
aria-expanded和aria-haspopup属性需 JS 同步更新,否则屏幕阅读器无法识别状态 - 键盘导航(Tab / Arrow / Esc)必须手写逻辑,否则 Tab 键卡在一级就进不去二级
真正难的不是让菜单“显示出来”,而是让焦点流可控、移动端不误触、屏幕阅读器能理解、小屏不溢出——这些没法靠堆 CSS 解决,必须逐层用 JS 接管。别指望“一个 class 解决所有问题”。


















