2026年5月20日

2026年5月20日

WordPressのFlexboxナビゲーションを実装する方法

はじめに

WordPressのナビゲーションは wp_nav_menu() でHTML出力し、CSSのFlexboxでスタイリングするのが標準的なアプローチです。モバイル向けのハンバーガーメニュー・ドロップダウンサブメニュー・キーボード操作対応まで一気に実装する方法を解説します。

症状・原因

  • ナビゲーションメニューがレスポンシブになっていない
  • ハンバーガーメニューを自作したい
  • ドロップダウンメニューがホバーでしか開かない
  • キーボードでメニューを操作できない

解決手順

ステップ1:wp_nav_menu()の基本設定

// functions.php: メニュー位置を登録
add_action('after_setup_theme', function(): void {
    register_nav_menus([
        'primary' => 'メインナビゲーション',
        'footer'  => 'フッターナビゲーション',
    ]);
});
// header.php: メニューを出力
<nav class="site-nav" role="navigation" aria-label="メインナビゲーション">
    <button class="nav-toggle" aria-expanded="false" aria-controls="primary-menu">
        <span class="sr-only">メニュー</span>
        <span class="hamburger" aria-hidden="true"></span>
    </button>
    <?php wp_nav_menu([
        'theme_location' => 'primary',
        'menu_id'        => 'primary-menu',
        'menu_class'     => 'nav-menu',
        'container'      => false,
    ]); ?>
</nav>

ステップ2:FlexboxでCSSを組む

/* ナビゲーション全体 */
.site-nav {
    display: flex;
    align-items: center;
    justify-content: space-between;
}

/* メニューリスト */
.nav-menu {
    display: flex;
    align-items: center;
    gap: 0;
    list-style: none;
    margin: 0;
    padding: 0;
}

/* 各メニュー項目 */
.nav-menu > li > a {
    display: block;
    padding: 0.75rem 1.25rem;
    color: #1d2327;
    text-decoration: none;
    font-weight: 500;
    transition: color 0.15s;
}

.nav-menu > li > a:hover,
.nav-menu > li.current-menu-item > a {
    color: #2271b1;
}

/* ドロップダウンサブメニュー */
.nav-menu .sub-menu {
    display: none;
    position: absolute;
    top: 100%;
    left: 0;
    min-width: 200px;
    background: #fff;
    border: 1px solid #e2e4e7;
    border-radius: 4px;
    box-shadow: 0 4px 12px rgba(0,0,0,0.1);
    list-style: none;
    padding: 0.5rem 0;
    z-index: 100;
}

.nav-menu li {
    position: relative;
}

.nav-menu li:hover > .sub-menu,
.nav-menu li:focus-within > .sub-menu {
    display: block;
}

ステップ3:ハンバーガーメニュー

/* ハンバーガーボタン(デスクトップでは非表示) */
.nav-toggle {
    display: none;
    background: none;
    border: none;
    cursor: pointer;
    padding: 0.5rem;
}

.hamburger,
.hamburger::before,
.hamburger::after {
    display: block;
    width: 24px;
    height: 2px;
    background: currentColor;
    transition: transform 0.3s, opacity 0.3s;
}

.hamburger {
    position: relative;
}

.hamburger::before,
.hamburger::after {
    content: '';
    position: absolute;
}

.hamburger::before { top: -7px; }
.hamburger::after  { top:  7px; }

/* 開いた状態: × マーク */
.nav-toggle[aria-expanded="true"] .hamburger {
    background: transparent;
}
.nav-toggle[aria-expanded="true"] .hamburger::before {
    transform: rotate(45deg) translate(5px, 5px);
}
.nav-toggle[aria-expanded="true"] .hamburger::after {
    transform: rotate(-45deg) translate(5px, -5px);
}

@media (max-width: 768px) {
    .nav-toggle { display: flex; }

    .nav-menu {
        display: none;
        flex-direction: column;
        position: absolute;
        top: 100%;
        left: 0;
        right: 0;
        background: #fff;
        border-top: 1px solid #e2e4e7;
        padding: 1rem 0;
    }

    .nav-menu.is-open { display: flex; }
}

ステップ4:JavaScriptでトグル制御

// ハンバーガーメニューのトグル
const toggle = document.querySelector('.nav-toggle');
const menu   = document.querySelector('#primary-menu');

if (toggle && menu) {
    toggle.addEventListener('click', () => {
        const isOpen = toggle.getAttribute('aria-expanded') === 'true';
        toggle.setAttribute('aria-expanded', String(!isOpen));
        menu.classList.toggle('is-open', !isOpen);
    });

    // ESCキーで閉じる
    document.addEventListener('keydown', (e) => {
        if (e.key === 'Escape' && menu.classList.contains('is-open')) {
            toggle.setAttribute('aria-expanded', 'false');
            menu.classList.remove('is-open');
            toggle.focus();
        }
    });
}

注意事項

  • :focus-within でサブメニューを開く実装はキーボード操作に対応しています。ホバーのみの実装はキーボードユーザーが使えません
  • aria-expanded は必ず JavaScript で同期させてください。スクリーンリーダーがメニューの開閉状態を読み上げます
  • モバイルメニューを display: none で非表示にする場合、visibility: hidden と組み合わせてフォーカスが当たらないようにしてください

まとめ

wp_nav_menu() でHTML出力し、Flexboxで横並びレイアウトを組みます。ハンバーガーメニューは aria-expanded + is-open クラスのトグルで実装します。ドロップダウンは :hover:focus-within を組み合わせてキーボードアクセシビリティに対応させます。

お気軽にご相談ください

お見積りへ お問い合わせへ