ハンバーガーメニューをjQueryで実装する方法と現場での選択基準
この記事には広告リンクを含みます。紹介している商品・サービスの一部はアフィリエイトプログラムを利用しています。 商品・サービスの選定はご自身の判断でお願いいたします。
スマホでサイトを開き、ハンバーガーアイコンをタップしても何も起きない。
こうした実装トラブルは、コーディング現場でよく出会います。
実装自体は難しくありませんが、WordPressの読み込み順序やvanilla JSとの使い分けで詰まるケースが多い印象です。
この記事では、jQueryによる最小実装と、WordPressならではの二重読み込み回避策、そしてvanilla JSとの選択基準を整理します。
コピペで動くコードより、「なぜそう書くか」の判断軸を持って帰ってください。
jQueryでハンバーガーメニューを実装する最小コード
jQueryでハンバーガーメニューを動かすには、クラスのトグルとaria-expandedの管理が核になります。
コードを書く前に、マークアップの選択が動作品質を左右します。
button要素を使う理由
ハンバーガーボタンは<div>ではなく<button>要素で作ってください。<div>はキーボードのTabキーでフォーカスが当たらず、スクリーンリーダーにも「ボタン」として認識されません。<button>ならブラウザがデフォルトでフォーカスを当て、Enterキーでも発火します。
アクセシビリティの基本であると同時に、実装ミスを防ぐ手堅い選択です。aria-expanded属性は、メニューの開閉状態をスクリーンリーダーに伝えます。trueでメニュー展開中、falseで閉じていることを示します。
<button class="menu-toggle" aria-expanded="false" aria-controls="nav-menu">
<span class="bar"></span>
<span class="bar"></span>
<span class="bar"></span>
</button>
<nav id="nav-menu" hidden>
<ul>
<li><a href=""#about">About</a></li>"
<li><a href=""#service">Service</a></li>"
<li><a href=""#contact">Contact</a></li>"
</ul>
</nav>×変形アニメーションはCSSだけで完結
三本線を×マークに変形するアニメーションは、CSSのみで実現できます。
JavaScriptで直接スタイルを書き換える必要はありません。
クラスを付け外しして、CSS側でトランジションを受け取る構成が保守しやすいです。
.menu-toggle .bar {
display: block; width: 24px; height: 2px;
background: #333;
transition: transform 0.3s, opacity 0.3s;
}
.menu-toggle.is-open .bar:nth-child(1) { transform: translateY(8px) rotate(45deg); }
.menu-toggle.is-open .bar:nth-child(2) { opacity: 0; }
.menu-toggle.is-open .bar:nth-child(3) { transform: translateY(-8px) rotate(-45deg); }jQueryのコードはクラス管理と属性更新に絞ります。
開いたメニューでページ内リンクを押してもメニューが閉じない問題は、ナビ内アンカーへのクリックイベント追加で解決できます。
この処理を入れていない実装は現場でよく見かけます。
$(function () {
var $toggle = $('.menu-toggle');
var $nav = $('#nav-menu');
$toggle.on('click', function () {
var expanded = $(this).attr('aria-expanded') === 'true';
$(this).attr('aria-expanded', !expanded).toggleClass('is-open');
$nav.prop('hidden', expanded);
});
// ページ内リンクでメニューを閉じる
$nav.find('a').on('click', function () {
$toggle.attr('aria-expanded', 'false').removeClass('is-open');
$nav.prop('hidden', true);
});
});WordPressでjQueryを使うとき、CDN追加が不要な理由
WordPressサイトでjQueryを使う場合、CDNからの追加読み込みは基本的に不要です。
自分が触れてきた範囲では、WordPressテーマがjQueryをすでに読み込んでいるケースがほとんどです。
自分で<script>タグやCDNリンクを追加すると、同じライブラリが2回読み込まれて競合が起きます。
二重読み込みのよくある症状:
$ is not definedやCannot read properties of undefinedがコンソールに出る
対処の前に、ブラウザの開発者ツール(ネットワークタブ)でjQueryが何回読まれているか確認してください。
1回だけなら追加不要、2回以上あれば競合が疑われます。
自分がWordPress案件で最初にやることのひとつが、このチェックです。
WordPressでJSファイルを安全に追加するには、wp_enqueue_scriptを使ってください。
依存配列に'jquery'を指定するだけで、読み込み順序をWordPressが保証します。
// functions.php
function my_theme_scripts() {
wp_enqueue_script(
'my-menu',
get_template_directory_uri() . '/js/menu.js',
['jquery'], // jQueryへの依存を宣言
'1.0.0',
true // フッターに出力
);
}
add_action('wp_enqueue_scripts', 'my_theme_scripts');テーマ側のjQueryをそのまま流用でき、追加ファイルだけを読み込む構成になります。
CDNリンクを直書きする方法と比べて、バージョン管理とキャッシュ制御も楽になります。
WordPress案件では、まずこの方法から試してください。
jQuery vs vanilla JS:案件スタックで選ぶ判断基準
ハンバーガーメニュー程度の実装なら、vanilla JSで十分に書けます。
それでも現場でjQueryを使う理由は「すでに入っているから」がほとんどです。
自分の案件では、以下の基準で判断しています。
環境 | 選択 | 理由 |
|---|---|---|
WordPress(テーマ依存あり) | jQuery | 追加コストなし、競合なし |
既存jQueryプラグイン多用 | jQuery | 統一で保守しやすい |
Astro / Next.js など | vanilla JS | jQueryのバンドルコストが割に合わない |
小規模LP・新規静的案件 | vanilla JS | 依存を増やさず軽量に保てる |
WordPressの場合、テーマが読み込むjQueryをそのまま使えるため追加コストが実質ゼロです。
プラグインとの統一感もあり、保守を別の人に引き継ぐときも迷いにくい選択です。
Astro環境でjQueryを使おうとすると、npm install jqueryしてバンドル設定を変える手順が必要になります。
自分がAstroで初クライアント案件を対応したとき、モジュール解決まわりで想定外の手間が増えました。
モダン環境ではdocument.querySelectorとclassList.toggleで同じ動作を書けるため、jQueryを入れる理由がほとんどありません。
Astro環境での技術選定についてはAstroとWordPressの使い分け:迷わない3つの判断基準も参考にしてください。
vanilla JSで書く最小実装は以下です。
jQueryとほぼ同じ構造なので、切り替えのハードルは高くありません。
const toggle = document.querySelector('.menu-toggle');
const nav = document.querySelector('#nav-menu');
toggle.addEventListener('click', () => {
const expanded = toggle.getAttribute('aria-expanded') === 'true';
toggle.setAttribute('aria-expanded', String(!expanded));
toggle.classList.toggle('is-open');
nav.hidden = expanded;
});
nav.querySelectorAll('a').forEach(link => {
link.addEventListener('click', () => {
toggle.setAttribute('aria-expanded', 'false');
toggle.classList.remove('is-open');
nav.hidden = true;
});
});実装後のチェックとして、スマホでメニューが3タップ以内で完結するか確認してください。
自分は問い合わせページへの導線を必ずスマホ実機で確認します。
ハンバーガーの開閉アニメーションが重いとそれだけで離脱につながります。
コードの動作確認と合わせて、導線の軽さも見てください。
まとめ
- jQueryの最小実装は
toggleClassとaria-expanded管理の組み合わせ - ×変形アニメーションはCSSだけで完結
- WordPressではCDN追加不要、
wp_enqueue_scriptの依存宣言で安全に読み込む - Astroなどのモダン環境ではvanilla JSが適切、jQueryのバンドルコストは割に合わない
- 実装後はスマホでの3タップ導線チェックを忘れずに
コーディング代行・実装判断で詰まったら Build に振ってください。