用途
Megamenu 是一种大型、多列的下拉面板,从导航栏展开,展示结构化的链接集合、分类,有时还包含推广内容。与标准下拉菜单不同,Megamenu 使用页面全部或接近全部的宽度,一次性组织大量导航选项。它帮助用户无需反复点击即可浏览庞大的导航结构,因此成为企业、电商和内容密集型网站的常见选择。
何时使用
当需要在单个可扫描的面板中展示大量分类导航选项时,使用 Megamenu。常见场景包括:
- 拥有数十个产品类别和子类别的电商网站
- 按领域组织众多功能的企业平台
- 拥有大量部门导航的大学或政府网站
- 拥有众多编辑栏目和子栏目的新闻门户
- 功能集复杂、需要有序访问的 SaaS 产品
何时避免
- 导航链接总数少于 10-15 个的网站(简单下拉菜单即可)
- 屏幕宽度不足的纯移动端应用
- 导航需求极少的单一用途落地页
- 相比广度更看重简洁性和访问速度的网站
- 分析数据显示用户更偏好搜索而非浏览分类的网站
实现流程
- 在复制示例前,确认该模式与问题和约束相匹配。
- 从 references/pattern.md 中的结构和示例开始,然后选择最小可行的变体。
- 在叠加视觉打磨之前,先应用无障碍、性能和交互护栏。
- 使用测试指南验证键盘、屏幕阅读器、响应式和失败场景下的行为。
无障碍护栏
应做 ✅
- 在触发按钮上使用 aria-haspopup="true" 和 aria-expanded
- 支持键盘导航:Enter/Space 打开,Escape 关闭,方向键在项目间移动
- 将分类标题作为非交互标签(role="presentation" 或标题元素)
- 确保打开面板内的所有链接都可通过 Tab 键到达
- 当焦点完全离开 Megamenu 时关闭面板
不应做 ❌
- 不要仅靠悬停打开 Megamenu 而没有点击/键盘替代方案
- 不要将焦点永久困在面板内——允许 Tab 离开并关闭菜单
- 不要错误使用自定义角色(除非实现完整的菜单键盘模式,否则避免 role="menu")
性能护栏
目标指标
- 面板渲染:从触发激活到面板可见 < 100ms
- 悬停意图延迟:200-300ms,防止意外触发
- 动画:打开/关闭过渡 200ms、60fps
- DOM 节点:尽量少——仅在首次打开时惰性渲染面板内容
- 包体积:Megamenu 组件逻辑 < 5KB
优化策略
惰性渲染面板内容
const [hasOpened, setHasOpened] = useState(false);
const open = () => { setHasOpened(true); setIsOpen(true); };
// Only render panel DOM after first open
{hasOpened && }
常见错误
无悬停意图延迟
问题:鼠标进入时 Megamenu 立即打开,导致用户移过导航栏时意外触发。
修复方法:在打开前添加 200-300ms 的悬停意图延迟。使用计时器,如果鼠标在延迟完成前离开触发器则取消。
鼠标移向面板时面板关闭
问题:触发器和面板之间的间隙导致触发器的 mouseleave 在面板的 mouseenter 之前触发,从而关闭菜单。
修复方法:使用共享的关闭延迟(300ms),当鼠标进入面板时取消。或者创建一个连接触发器和面板的不可见“桥接”元素。
无键盘导航
问题:用户只能用鼠标访问 Megamenu。键盘用户无法打开、导航或关闭面板。
修复方法:支持 Enter/Space 切换、Escape 关闭、方向键或 Tab 在链接间导航。关闭时将焦点返回触发器。
相关模式
- https://uxpatterns.dev/patterns/navigation/hambuger-menu
- https://uxpatterns.dev/patterns/navigation/navigation-menu
- https://uxpatterns.dev/patterns/navigation/sidebar
完整实现细节、示例和测试说明,请参见 references/pattern.md。
模式页面:https://uxpatterns.dev/patterns/navigation/megamenu