
本文详解如何在纯 css 实现的汉堡菜单基础上,扩展支持无限层级的嵌套下拉菜单,通过语义化 html 结构与精准的 css 选择器控制显示/隐藏逻辑,并提供可直接运行的完整示例代码。
要将当前单层汉堡菜单升级为真正可用的多级(multilevel)导航栏,关键不在于增加 JavaScript,而在于重构 HTML 语义结构 + 增强 CSS 的层级控制能力。你当前的
- 中所有
- 是平级的,无法表达“Link 2 包含 Link A/B”这样的父子关系——这正是嵌套失效的根本原因。
✅ 正确的 HTML 结构:语义化嵌套
必须使用
- 内嵌
? 要点: 使用 class="has-submenu" 标记可展开项; 子菜单统一用 class="submenu",并作为父 的直接子元素(非兄弟节点); 箭头符号(▼ / ▶)仅作视觉提示,不影响逻辑。
✅ CSS 增强:精准控制嵌套显示逻辑
在你原有 CSS 基础上,追加以下样式(无需修改现有动画逻辑):
/* 隐藏所有子菜单,默认收起 */ .menu .submenu { display: none; list-style: none; padding-left: 0; margin: 0; } /* 仅当父级 li 拥有 :hover 或被激活时,显示其子菜单 */ .menu > li:hover > .submenu, .menu > li.has-submenu.active > .submenu, .menu > li.has-submenu:focus-within > .submenu { display: block; position: static; /* 取消绝对定位干扰,保持流式布局 */ width: 100%; } /* 为子菜单项添加基础样式(与一级项一致) */ .menu .submenu > li { background-color: rgba(0, 0, 0, 0.6); padding: 0.4em 0.8em; } /* 可选:为深层菜单添加缩进效果 */ .menu .submenu .submenu { padding-left: 1.2em; }✅ 支持键盘与移动端的健壮性增强(推荐)
纯 hover 在触摸设备上不可靠。建议用 CSS :focus-within + 少量 JS 触发 active 类来兼顾可访问性:
/* 支持键盘焦点展开 */ .menu > li.has-submenu:focus-within > .submenu { display: block; }// 简洁 JS:点击时切换 active 状态(防 touch 误触) document.querySelectorAll('.has-submenu > a').forEach(el => { el.addEventListener('click', e => { e.preventDefault(); const parentLi = el.parentElement; parentLi.classList.toggle('active'); }); });⚠️ 注意事项
- ❌ 不要写
- …
- …
- 必须是
- 的子元素,不能是兄弟);
- ✅ 所有 .submenu 必须是
- 的直接子元素;
- ? 移动端建议禁用 :hover,主用 :focus-within + active 类控制;
- ? 箭头图标建议改用 SVG 或伪元素(:after),便于 CSS 控制旋转动画。
✅ 最终效果特点
- 一级菜单随汉堡按钮展开/收起(保留你原有的动画);
- 二级及更深菜单在悬停或点击父项时逐层展开,互不干扰;
- 完全响应式,适配桌面与移动设备;
- 无依赖库,纯 HTML/CSS/轻量 JS,性能友好。
通过结构先行、样式驱动、渐进增强的方式,你的导航栏即可从静态列表蜕变为专业级多级交互组件。
- ❌ 不要写










