bootstrap 5 原生不支持三级菜单,因dropdown插件仅初始化一级、二级菜单定位异常、css强制隐藏三级,需手动修正html结构、js控制显隐、css重定位及键盘导航支持。

Bootstrap 5 的导航栏原生不支持三级菜单,dropdown-menu 嵌套在另一个 dropdown-menu 内时,第三级默认始终 display: none,且无任何 JS 初始化、无 hover/click 响应、无键盘焦点流——这不是你写错了,是框架主动移除的。
为什么 .dropdown-menu .dropdown-menu 不生效
常见现象:HTML 结构看着嵌套正确,鼠标悬停或点击后三级菜单就是不出现。根本原因有三个:
-
dropdown插件只监听一级data-bs-toggle="dropdown",子级dropdown-menu完全没被实例化,show类不会自动加到三级上 - 二级菜单的
position: absolute默认相对body定位,若父级.dropdown-item没设position: relative,三级会飞出视口 - Bootstrap 5 默认对嵌套
.dropdown-menu .dropdown-menu加了opacity: 0和visibility: hidden,你的display: block被 CSS 层叠覆盖
必须加的 HTML 结构与 class 修正
不能靠堆 dropdown 类递归实现。要让三级“稳住”,结构必须显式分层,并打上可识别的自定义标记:
- 二级触发项(如“企业方案”)用
<li class="dropdown-submenu">,而非<li class="dropdown"> - 三级容器必须是二级
<li>的直接子元素,且带class="dropdown-menu dropdown-submenu",并加position-static防止 Popper 错位 - 给二级触发项里的链接或按钮加
data-bs-toggle="dropdown"和data-bs-popper="none",禁用 Popper 对三级的重定位干扰 - 所有三级菜单需手动补
aria-expanded="false"和aria-haspopup="true",否则屏幕阅读器无法识别
JS 必须接管显示/隐藏逻辑
纯 CSS :hover 在触屏和键盘导航中完全失效,且无法处理悬停断连(鼠标经过间隙时闪退)。必须用 JS 控制时机:
- 监听
.dropdown-submenu的mouseenter,调用bootstrap.Dropdown.getOrCreateInstance(subMenu).show() - 监听整个二级
.dropdown-menu的mouseleave,延迟 200ms 后再hide(),避免误关 - 点击时必须
e.stopPropagation(),否则会触发一级菜单收起 - 移动端需额外监听
click,并在touchstart上阻止默认行为,防止双击放大
CSS 定位与 z-index 补丁
默认所有下拉都向下展开,三级必须右向弹出,但 dropend 类只作用于一级,对子级无效:
- 强制三级定位:
.dropdown-submenu .dropdown-menu { position: absolute; top: 0; left: 100%; margin-top: -6px; } - 清除原生箭头错位:
.dropdown-submenu .dropdown-menu::before { display: none; } - 显式设
z-index: 1002(一级是 1000,二级 1001),否则三级会被兄弟菜单遮盖 - 小屏响应式降级:用
@media (max-width: 992px)把三级改为top: 100%; left: 0;垂直展开,避免横向溢出
最易被忽略的是键盘导航支持:Tab 键必须能顺序进入三级菜单,Esc 要逐级退出,arrowup/down 需在当前层级内循环——这些没法靠 class 自动继承,每一级都得手动绑定 keydown 事件并管理 focus 流。没做这步,就等于没做完。











