二级菜单需手动补全css:.dropdown-submenu .dropdown-menu{top:0;left:100%;margin-top:-1px;}.dropdown-submenu:hover .dropdown-menu,.dropdown-submenu:focus-within .dropdown-menu{display:block;}

下拉菜单二级菜单默认不显示,因为 .dropdown-menu 的 display 是 none
Bootstrap(5.x)默认只支持一级下拉,.dropdown-menu 本身是隐藏的,靠 JavaScript 切换 show 类控制显隐。二级菜单(即子菜单)没有内置样式,必须手动补全 CSS 触发逻辑。
关键点在于:二级菜单本身也要有 .dropdown-menu 类,并且它的父级 <li> 需要同时具备 .dropdown 类(不是 .dropdown-item),否则无法正确继承 hover/focus 行为。
- 二级菜单 HTML 必须嵌套在带
.dropdown类的<li>内,不能直接放在<a></a>或<button></button>里 - 需要为
.dropdown:hover .dropdown-menu, .dropdown:focus-within .dropdown-menu显式设置display: block,否则仅靠.show类不够(JS 不会自动给二级加show) - Bootstrap 5 默认禁用 hover 触发(为移动端兼容),所以必须自己加 hover/focus-within 支持
如何写二级菜单的 CSS 显示规则?
最简可行的 CSS 就三行,但缺一不可:
.dropdown-submenu .dropdown-menu {
top: 0;
left: 100%;
margin-top: -1px;
}
.dropdown-submenu:hover .dropdown-menu,
.dropdown-submenu:focus-within .dropdown-menu {
display: block;
}
注意:.dropdown-submenu 是你自定义的 wrapper 类名,用于标识二级触发项;top: 0 和 left: 100% 让二级菜单贴着右侧展开;margin-top: -1px 消除边框间隙。
- 不要用
visibility: hidden/visible替代display—— 这会导致点击穿透或焦点丢失 - 如果用了 Popper.js(Bootstrap 5 默认启用),可能需加
data-bs-popper="none"到二级<ul></ul>上,避免位置错乱 - 移动端需额外处理 touch 事件,纯 CSS hover 在 iOS Safari 上不可靠,建议保留 JS 手动 toggle
为什么二级菜单点击后立刻消失?
常见原因是二级菜单的 <ul></ul> 没被包裹在 .dropdown 容器内,导致鼠标移出触发项时,整个 dropdown 区域失去 focus/hover 状态,上级 .dropdown-menu 随之收起。
- 确保结构形如:
<li class="dropdown"> <a class="dropdown-toggle">一级</a><ul class="dropdown-menu"><li class="dropdown-submenu"> <a>二级入口</a><ul class="dropdown-menu">...</ul> </li></ul> </li> -
.dropdown-submenu必须是<li>,不能是<div> 或 <code><span></span>,否则语义和键盘导航会出问题 - 若使用 Bootstrap 5.3+,
focus-within在部分旧版 Safari 中失效,需 fallback 到 JS 监听mouseenter/mouseleave
二级菜单的定位偏移、层级遮挡、键盘焦点跳转,这三个地方最容易反复调试。别指望一次写对,先让 display 出来,再调位置,最后修交互细节。











