bootstrap 5 默认禁用 dropdown-menu 嵌套,子菜单不显示且无交互逻辑;需用 :focus-within + css 实现键盘可访问的巨型菜单,wordpress 中须通过自定义 walker 类动态输出结构,并手动处理响应式与焦点管理。

为什么直接嵌套 dropdown-menu 不生效
Bootstrap 5 默认禁止 dropdown-menu 嵌套,不是你 HTML 写错了,是框架主动移除支持。子菜单始终 display: none,且无 hover/click 逻辑;data-bs-toggle="dropdown" 不会递归初始化二级项,Popper 定位也默认不接管子级。常见现象是:鼠标悬停没反应、点击父项后整个下拉立刻收起、移动端一点就消失。
:focus-within + CSS 实现键盘可访问的巨型菜单
纯 CSS 方案可行,但必须放弃“只靠 :hover”的思路——它对键盘用户(Tab 导航)和屏幕阅读器无效。正确路径是用 :focus-within 配合结构约束:
- 把整个巨型菜单容器(如
<div class="mega-menu">)包在带 <code>tabindex="0"的<li class="dropdown-item">内 - 确保内部至少有一个可聚焦元素(如
<a href></a>或<button></button>) - CSS 触发条件写成
.dropdown-item:focus-within .mega-menu, .dropdown-item:hover .mega-menu - 必须给
.dropdown-item加position: relative,否则.mega-menu的left: 100%会相对 body 定位飞出视口 - 自定义
BS5_Mega_Walker类,在start_lvl()中判断是否含has-megaclass - 若为 mega 父级(
$depth === 0),输出<div class="dropdown-menu mega-menu p-3"><div class="row"> 而非 <code><ul></ul> - 子项(
$depth === 1)用<div class="col-sm-6 col-lg-3"> 包裹,而非 <code><li> - 务必在
start_el()中为 mega 父级<a></a>添加aria-haspopup="true" aria-expanded="false",JS 后续才好同步状态 - 在
@media (max-width: 992px)中重置二级菜单定位:top: 100%; left: 0;,让它垂直向下展开 - 移除
left: 100%和margin-left: -4px,避免小屏错位 - 给
.mega-menu加max-height: 70vh; overflow-y: auto;,防长列表撑爆视口 - 键盘导航时,按
Esc应关闭所有.show,需监听document级keydown并过滤.mega-menu.show
WordPress 中用 Walker 动态输出 MegaMenu 结构
硬写 HTML 没法对接数据库分类,得靠 PHP 层控制结构。WordPress 的 Walker_Nav_Menu 是唯一可靠方式:
响应式断裂点必须手动接管,不能依赖 dropend
Bootstrap 的 dropend / dropstart 只作用于一级 dropdown,对二级及以上完全无效。小屏下强行横向展开会导致内容溢出或被 overflow: hidden 切掉:
最易被忽略的是焦点管理:菜单展开后,焦点必须落到第一个可聚焦子元素上,否则键盘用户无法继续操作;而这个动作无法用纯 CSS 完成,必须 JS 补位。











