2026年5月20日

2026年5月20日

WordPressのドロップダウンメニューが機能しない場合の解決方法

はじめに

WordPressのドロップダウンメニュー(サブメニュー)が機能しない主な原因は「CSSのz-indexまたはdisplay設定」「JavaScriptのホバーイベント未設定」「タッチデバイスへの未対応」です。CSSとJSの修正で対応できます。

症状・原因

  • ドロップダウンメニューがホバーしても表示されない
  • サブメニューが他の要素の下に隠れる(z-index問題)
  • スマートフォンでドロップダウンが操作できない
  • メニューからカーソルが外れるとすぐ閉じてしまう

解決手順

ステップ1:メニュー構造を確認する

# メニューの階層構造を確認
wp menu item list メインメニュー --format=table

# サブメニューアイテムのparent_idを確認
wp eval "
\$menu_items = wp_get_nav_menu_items('メインメニュー');
foreach (\$menu_items as \$item) {
    \$indent = \$item->menu_item_parent ? '  └ ' : '';
    echo \$indent . \$item->title . ' (ID:' . \$item->ID . ', parent:' . \$item->menu_item_parent . ')' . PHP_EOL;
}"

# WordPressのメニューHTML構造を確認
# → .menu-item-has-children クラスが付く親アイテム
# → .sub-menu クラスが付くサブメニューのul要素

ステップ2:CSSでサブメニューを表示する

/* 子テーマの style.css — ドロップダウンの基本設定 */

/* サブメニューを非表示にしてホバーで表示 */
.nav-menu .sub-menu {
    display: none;
    position: absolute;
    top: 100%;
    left: 0;
    min-width: 200px;
    background-color: #ffffff;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
    z-index: 1000;        /* 他の要素の上に表示 */
    list-style: none;
    margin: 0;
    padding: 8px 0;
    border-radius: 4px;
}

/* 親メニューを relative にする */
.nav-menu .menu-item-has-children {
    position: relative;
}

/* ホバーでサブメニューを表示 */
.nav-menu .menu-item-has-children:hover > .sub-menu,
.nav-menu .menu-item-has-children:focus-within > .sub-menu {
    display: block;
}

/* サブメニューのリンクスタイル */
.nav-menu .sub-menu a {
    display: block;
    padding: 10px 16px;
    color: #1d2327;
    text-decoration: none;
    white-space: nowrap;
}

.nav-menu .sub-menu a:hover {
    background-color: #f0f0f1;
    color: #2271b1;
}

/* ネストしたサブメニュー(2階層目) */
.nav-menu .sub-menu .sub-menu {
    top: 0;
    left: 100%;
}

ステップ3:z-indexの問題を修正する

/* z-indexの競合を解決 */

/* ヘッダーのz-indexを確認・設定 */
.site-header {
    position: relative;
    z-index: 100;
}

/* スライダー・ヒーロー画像との競合 */
.hero-section {
    position: relative;
    z-index: 1;  /* ヘッダーより低くする */
}

/* ページビルダーが高いz-indexを設定している場合 */
.elementor-section {
    z-index: auto;  /* またはヘッダーより低い値 */
}

/* デバッグ: z-indexを可視化 */
/* DevToolsの Layers タブでz-indexのスタック順を確認 */

ステップ4:タッチデバイス対応のJavaScriptを追加する

// js/dropdown.js — タッチデバイスでのドロップダウン対応
document.addEventListener('DOMContentLoaded', function () {
    const menuItems = document.querySelectorAll('.menu-item-has-children');

    menuItems.forEach(function (item) {
        const link    = item.querySelector('a');
        const submenu = item.querySelector('.sub-menu');

        if (!submenu) return;

        // タッチデバイス用: 最初のタップでサブメニュー表示
        link.addEventListener('click', function (e) {
            if (!item.classList.contains('is-open') && window.matchMedia('(max-width: 768px)').matches) {
                e.preventDefault();
                // 他のメニューを閉じる
                menuItems.forEach(function (other) {
                    if (other !== item) other.classList.remove('is-open');
                });
                item.classList.toggle('is-open');
            }
        });

        // aria属性を付与
        link.setAttribute('aria-haspopup', 'true');
        link.setAttribute('aria-expanded', 'false');
        item.addEventListener('mouseenter', function () {
            link.setAttribute('aria-expanded', 'true');
        });
        item.addEventListener('mouseleave', function () {
            link.setAttribute('aria-expanded', 'false');
        });
    });

    // メニュー外タップで閉じる
    document.addEventListener('click', function (e) {
        if (!e.target.closest('.menu-item-has-children')) {
            menuItems.forEach(function (item) {
                item.classList.remove('is-open');
            });
        }
    });
});

ステップ5:CSSでモバイルの is-open を制御する

/* モバイルのドロップダウン: is-openクラスで制御 */
@media (max-width: 768px) {
    .nav-menu .menu-item-has-children > .sub-menu {
        display: none;
        position: static;  /* モバイルでは通常フロー */
        box-shadow: none;
        background-color: #f6f7f7;
        padding-left: 16px;
    }

    .nav-menu .menu-item-has-children.is-open > .sub-menu {
        display: block;
    }

    /* 親メニューにアイコンを追加 */
    .nav-menu .menu-item-has-children > a::after {
        content: ' ▼';
        font-size: 0.7em;
    }

    .nav-menu .menu-item-has-children.is-open > a::after {
        content: ' ▲';
    }
}

ステップ6:functions.phpでJSを読み込む

// 子テーマの functions.php
add_action('wp_enqueue_scripts', function(): void {
    wp_enqueue_script(
        'dropdown-menu',
        get_stylesheet_directory_uri() . '/js/dropdown.js',
        [],
        wp_get_theme()->get('Version'),
        true
    );
});

注意事項

  • position: absolute のサブメニューを表示するには、親要素に position: relative が必要です
  • z-index はページビルダーや他のプラグインが高い値を設定していることがあります。DevToolsの「Layers」タブで確認してください
  • focus-within 疑似クラスを使うとキーボード操作でもサブメニューが開き、アクセシビリティが向上します

まとめ

ドロップダウンメニューが機能しない場合は「親要素にposition: relative → サブメニューにposition: absolute + z-index: 1000 → :hoverで表示 → タッチデバイス用JSを追加」の順で修正します。

お気軽にご相談ください

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