【初心者向け】ハンバーガーメニューの「ボタンは動くのにメニューが表示されない」原因と対処法
スマホサイトやレスポンシブサイトでよく使うハンバーガーメニュー。
「ボタンを押すと(アニメーションは動く)でもメニューリストが表示されない!」という状態に悩んだことはありませんか?
原因は意外と単純な箇所にあることが多いです。本記事では初心者向けに原因の探し方と具体的な対処法を、実際のコード例とともに丁寧に解説します。
TOC
この記事の要点(先に結論)
- 一番多い原因は CSS の
overflow(特にoverflow-x: hidden;)でメニューが切り取られていること。 - 他に、
z-indexの指定ミス・誤ったクラス名/ID・positionの関係で重なり順が期待通りになっていないこともある。 - ブラウザの検証ツール(devtools)で要素を確認すると短時間で原因が見つかる。
再現サンプル(そのままコピペで試せる最小例
HTML
<button id="hamburger" aria-expanded="false" aria-controls="nav">
☰
</button>
<nav id="nav" class="nav">
<ul>
<li><a href="#">Home</a></li>
<li><a href="#">サービス</a></li>
<li><a href="#">料金</a></li>
<li><a href="#">Contact</a></li>
</ul>
</nav>
CSS(問題になりやすいパターン)
/* 全体に overflow-x を指定しているとメニューが切られることがある */
html, body {
margin: 0;
padding: 0;
overflow-x: hidden; /* ← これが原因になることがある */
}
/* メニューの基本スタイル(画面右から出てくる例) */
.nav {
position: fixed;
top: 0;
right: -300px; /* 初期は画面外 */
width: 300px;
height: 100vh;
background: #fff;
box-shadow: -4px 0 10px rgba(0,0,0,0.1);
transition: right 0.3s ease;
z-index: 1000; /* 前面に出したいが、overflowがあると見えない */
}
/* 開いたとき */
.nav.open {
right: 0;
}
JavaScript(シンプルなトグル)
const btn = document.getElementById('hamburger');
const nav = document.getElementById('nav');
btn.addEventListener('click', () => {
const isOpen = nav.classList.toggle('open');
btn.setAttribute('aria-expanded', isOpen ? 'true' : 'false');
});
起きていた現象と今回の解決
- ボタン(赤矢印)は押せて、アニメーションも動く → JavaScript は機能している。
- しかしメニューリストが表示されない → 見た目上は「要素が切り取られている」状態でした。
- CSS を確認すると
overflow-x: hidden;がグローバルに指定されていました。 overflow-x: hidden;は画面からはみ出した横方向の要素を切り取るため、スライドして現れるメニュー(横から出るもの)は見えなくなります。- 対処:
overflow-x: hidden;を削除、またはグローバルではなく必要な要素にだけ適用。さらに.navにmax-widthを指定してレイアウト崩れを防ぐ。結果、メニューが正しく表示されました。


よくある原因と対処法チェックリスト
- overflow が原因か確認する
html, bodyや親要素にoverflow-x: hidden/overflow: hiddenがないか確認。- 一時的に無効化して(ブラウザ devtools で)挙動が変わるか試す。
- z-index と position の関係
z-indexはpositionが付いている要素にしか効かない(position: relative | absolute | fixed | sticky)。- メニュー要素と重なる親要素に
z-indexが高く設定されていないか確認。
- クラス名/ID のタイポ
- JS で操作している ID/class と HTML 側が一致しているか(大文字小文字も注意)。
document.getElementById('nav')としているのに、実際はid="navigation"といった単純ミスをよく見る。
- display / visibility の影響
display: noneのままになっていないか。アニメーションでtransformを使う場合はdisplayを変えずtransform/opacityを使う方が滑らか。
- 親要素の overflow や transform
- 親要素に
transformがあると、その子要素のz-indexの振る舞いが変わる(新しい stacking context ができる)。親のスタイルを確認。
- 親要素に
- JavaScript のエラー
- ブラウザのコンソールにエラーがないか必ず確認。JS の早期エラーで以後の処理が止まっている場合がある。
devtools(検証ツール)を使った素早い調査手順
- メニューを開こうとしている状態で右クリック → 「検証(Inspect)」を開く。
- Elements パネルでナビ要素(
#navなど)を探す。 - 要素が DOM 上に存在するかを確認(存在しないならJSで追加されていない)。
- Styles(右側)で
overflow/position/z-index/transformを確認。該当スタイルを一時的にオフにして挙動を観察。 - Console タブでエラー確認(JS のエラーは処理停止の原因)。
- 要素に
right: -300pxのような位置指定がある場合、実際にrightが変わっているか(class の付け外しで)確認。
さらに安定させるための小ワザ
- グローバルに
overflow-x: hiddenを指定する代わりに、必要なコンテナ一つにだけ指定する。 - スライドインメニューには
transform: translateX()を使う(right等よりも滑らかでパフォーマンスが良い)。 - 見え方に問題が出る場合、
position: fixed; z-index: 9999;などで強めに前面配置する。ただし stacking context(親の transform や z-index)に注意。 - アクセシビリティ:メニュー開閉時は
aria-expandedを更新し、フォーカストラップやスクリーンリーダー対応も検討する。
改良されたサンプル(transform を使った例)
/* 推奨:transform を使ってスライド */
.nav {
position: fixed;
top: 0;
right: 0;
transform: translateX(100%); /* 画面外へ移動 */
width: 300px;
height: 100vh;
transition: transform 0.3s ease;
z-index: 9999;
}
.nav.open {
transform: translateX(0); /* 元の位置に戻す */
}
See the Pen Untitled by 須山比佐代 (@awlsizua-the-scripter) on CodePen.
この方法だと親の overflow-x: hidden の影響を受けにくく、アニメーションも滑らかです。
まとめ(初心者向けの実践ポイント)
- まず devtools で要素が DOM にあるか確認。
overflow-x: hiddenは危険。グローバル指定しているならまず疑う。z-indexはpositionと stacking context の影響を受ける。親要素のtransformや別のz-indexに注意。- 小さく再現できるサンプルで原因を切り分ける(問題を局所化するのが早道)。
- 最後にアクセシビリティ(
aria-expanded等)を忘れずに。
Programming Notes


JavaScriptでクリックしても動かない?onclickとaddEventListenerの違いを初心者向けに徹底解説!2025
JavaScriptでボタンをクリックしても動かない…そんなときはonclickとaddEventListenerの違いを理解すれば解決します! 本記事では、動かない原因から正しい書き方、即実行…
Programming Notes


【初心者必見】ナビゲーションメニューでスムーズスクロールを完全ガイド|HTML・CSS・JavaScript徹底解説2…
初心者でも簡単に理解できる、ナビゲーションメニューから各セクションへスムーズスクロールさせる方法を解説。HTML・CSS・JavaScript対応で、最新2025年版の完全ガイド。…
その他関連記事はこちら→Programming Notes

Comments