本文详解如何在 wordpress 移动端导航中实现「悬停显示子菜单」效果,解决子菜单默认常驻展开的问题,通过纯 css 实现响应式 hover 展开逻辑,并兼顾可访问性与移动端兼容性。
本文详解如何在 wordpress 移动端导航中实现「悬停显示子菜单」效果,解决子菜单默认常驻展开的问题,通过纯 css 实现响应式 hover 展开逻辑,并兼顾可访问性与移动端兼容性。
在 WordPress 主题开发中,移动端导航(尤其是使用 wp_nav_menu() 生成的响应式菜单)常面临一个典型问题:子菜单(.sub-menu)默认始终可见或无法按需展开,违背了用户对“点击/悬停触发”的直觉交互预期。尤其当您已为桌面端设计了 hover 效果,却在移动设备上发现子菜单“永久显示”或“完全不显示”,往往是因为 CSS 选择器作用域、媒体查询冲突或 HTML 结构未被正确识别所致。
核心解决方案非常简洁,但需确保结构与样式精准匹配:
/* 默认隐藏所有子菜单 */
ul.sub-menu {
display: none;
}
/* 当父级菜单项被悬停时,显示其直接子菜单 */
.menu-item-has-children:hover > .sub-menu,
.menu-item-has-children:focus-within > .sub-menu {
display: block;
}
✅ 关键说明:
- .menu-item-has-children 是 WordPress 自动为含子菜单的菜单项添加的标准 class(见您 HTML 中
- 使用 > 直接子选择器可避免嵌套多层子菜单意外展开;
- 同时添加 :focus-within 是重要可访问性增强——当用户用键盘 Tab 导航至父链接时,子菜单也能正确显示,满足 WCAG 2.1 标准;
- 无需 JavaScript 干预,纯 CSS 驱动,性能更优、兼容性更好(支持所有现代浏览器及 iOS Safari)。
⚠️ 您原代码中的主要问题:
- #nav-primary :hover ul 选择器无效 —— 您的 HTML 中并无 #nav-primary ID,实际容器是 #mobile-menu 或 .mobile-menu;
- .sub-menu{ display:none; } 单独声明虽隐藏了菜单,但缺少触发显示的对应规则;
- 移动端 CSS 中存在冲突语句:#access ul li:hover > ul { display: none; }(末尾多出分号且逻辑相反),这会强制覆盖 hover 行为,务必删除;
- 当前结构中 .sub-menu 是
- 的直接子元素(如
- ... ),因此必须使用 .menu-item-has-children:hover > .sub-menu 而非 .menu-item-has-children:hover ul(后者可能命中深层嵌套)。
? 推荐增强实践(可选):
为提升移动端体验,建议结合媒体查询做智能适配:
/* 桌面端:启用 hover 展开 */
@media (min-width: 601px) {
ul.sub-menu {
display: none;
}
.menu-item-has-children:hover > .sub-menu,
.menu-item-has-children:focus-within > .sub-menu {
display: block;
}
}
/* 移动端(≤600px):禁用 hover,改用 JS 点击切换(更符合触控习惯)*/
@media (max-width: 600px) {
ul.sub-menu {
max-height: 0;
overflow: hidden;
transition: max-height 0.3s ease-out, opacity 0.2s;
}
.menu-item-has-children.active > .sub-menu {
max-height: 500px;
opacity: 1;
}
}
然后在移动端添加轻量 JS 切换逻辑(替代冗余的 onclick="twentytwentyoneExpandSubMenu(this)"):
document.querySelectorAll('.menu-item-has-children > .sub-menu-toggle').forEach(button => {
button.addEventListener('click', function(e) {
e.preventDefault();
const parentLi = this.closest('.menu-item-has-children');
parentLi.classList.toggle('active');
});
});
? 总结: 实现子菜单悬停显示的本质是「精准控制 display 状态 + 正确绑定触发条件」。优先使用 CSS :hover 和 :focus-within 实现桌面端交互,对移动端则推荐切换为点击展开(更符合触控范式)。务必检查 HTML 输出是否包含 menu-item-has-children 类,并移除任何反向覆盖的 display: none 规则。调试时可临时添加 outline: 1px solid red 到 .sub-menu 快速验证样式是否生效。











