WordPress 主题做响应式导航:wp_nav_menu 之后还得补这几段

· wordpress · 阅读 16
摘要

wp_nav_menu() 输出的是一段纯

    ,后台菜单里配好层级、主题里调用一行就能出结果。但它只解决「输出结构」,移动端的展开、收合、点击区域,全得自己补。 第一步:给菜单一个可控的容器 直接输出 ul 的问题是没法加开关按钮。标

wp_nav_menu() 输出的是一段纯 <ul>,后台菜单里配好层级、主题里调用一行就能出结果。但它只解决「输出结构」,移动端的展开、收合、点击区域,全得自己补。

第一步:给菜单一个可控的容器

直接输出 ul 的问题是没法加开关按钮。标准做法是把它包起来:

<nav class="site-nav">
  <button class="nav-toggle" aria-expanded="false" aria-controls="primary-menu">菜单</button>
  <?php wp_nav_menu(array(
    'theme_location' => 'primary',
    'container'      => false,
    'menu_id'        => 'primary-menu',
    'menu_class'     => 'nav-list',
  )); ?>
</nav>

container => false 很关键,否则 WP 会再套一层 div,CSS 选择器全乱。

第二步:断点内切换,而不是两套菜单

常见的错误做法是注册两个菜单位置,桌面一个、移动一个,内容得维护两遍。正确做法是一套结构,靠 CSS 控制显隐:

.nav-list { display: flex; gap: 1.5rem; }
@media (max-width: 768px) {
  .nav-list { display: none; flex-direction: column; }
  .nav-list.is-open { display: flex; }
}

第三步:aria 状态跟着 class 走

const btn = document.querySelector('.nav-toggle');
const list = document.getElementById('primary-menu');
btn.addEventListener('click', () => {
  const open = list.classList.toggle('is-open');
  btn.setAttribute('aria-expanded', open);
});

别把开关写在 CSS 的 :hover 上。触屏没有 hover,桌面用户手一滑菜单就消失,这是移动端导航最常见的返工点。

一个容易忽略的点

子菜单的展开在移动端通常要改成点击而不是 hover,WP 输出的子菜单 ul.sub-menu 默认嵌在 li 里,加一段 JS 拦截父级链接的点击即可。不用装第三方插件,二十行内能写完。