Bootstrap 5 默认不支持多级下拉菜单,因官方移除二级及以上嵌套支持,子菜单默认 display: none 且无 hover/focus 逻辑;需用 CSS + JS 补全,如 .dropdown-menu .dropdown:hover .dropdown-menu { display: block; } 并修正定位与 z-index。

Bootstrap 5 默认不支持多级下拉菜单
Bootstrap 5 官方移除了对二级及以上 dropdown-menu 的原生支持,所有嵌套的 dropdown-menu 默认被设为 display: none 且无 hover/focus 触发逻辑。这不是 bug,是设计取舍——官方认为多级菜单在移动端体验差、可访问性弱。如果你确实需要(比如后台管理系统的侧边导航或顶部全局菜单),就得自己补全 CSS + 少量 JS。
用 :hover + > 选择器实现纯 CSS 二级展开
最轻量的方案是仅支持鼠标悬停展开二级菜单,不依赖 JS。关键点在于解除子菜单的隐藏,并确保父级 dropdown-item 能正确触发:
- 必须给父级
dropdown-item添加position: relative,否则子dropdown-menu会脱标定位错乱 - 子
dropdown-menu需设position: absolute; left: 100%; top: 0;实现右向展开 - 仅靠
.dropdown:hover .dropdown-menu不够——它会一次性展开所有嵌套层。应限定层级:.dropdown-menu .dropdown:hover .dropdown-menu - 为避免移动端误触,建议加媒体查询限制:仅
@media (min-width: 992px)生效
.dropdown-menu .dropdown:hover .dropdown-menu {
display: block;
}
.dropdown-menu .dropdown:hover > .dropdown-item {
position: relative;
}
.dropdown-menu .dropdown:hover .dropdown-menu {
top: 0;
left: 100%;
margin-top: -1px;
}
三级及以上需递归类名或 JS 控制
CSS 本身无法真正“递归”,所谓“三级”实际是手动写死选择器链,例如:
.dropdown-menu .dropdown:hover .dropdown-menu .dropdown:hover .dropdown-menu
这种写法脆弱且不可维护。更现实的做法是:
立即学习“前端免费学习笔记(深入)”;
- 给每一级下拉容器统一加一个类名,如
dropdown-submenu - 用
.dropdown-submenu:hover .dropdown-menu替代深度嵌套选择器 - 若需键盘导航(Tab / Arrow)或移动端点击展开,则必须用 JS 监听
click或focusin,并动态切换show类 - 注意
aria-expanded和aria-haspopup属性需同步更新,否则屏幕阅读器无法识别状态
常见崩溃点:dropdown-menu 脱离父容器定位
最常遇到的问题是子菜单飞到页面左上角或完全不可见。根本原因通常是:
- 父级
.dropdown没有position: relative(尤其当它被 flex 或 grid 包裹时) - 子
.dropdown-menu的position: absolute找不到最近的非static定位祖先 - Bootstrap 5 的
.dropdown-menu默认带top: 100%,但二级菜单需要的是left: 100%,必须显式覆盖 - 使用
data-bs-popper="none"禁用 Popper 后,未手动补全定位逻辑,导致坐标计算失效
解决方法不是删 Popper,而是保留它,并通过 popperConfig 调整策略,或者直接放弃 Popper 改用纯 CSS 定位——后者更可控,但也意味着放弃自动翻转、防溢出等能力。


















