ハンバーガーメニュー展開時に背景をスクロールさせない方法

当サイトはアフィリエイト広告を使用しています。

ハンバーガーメニューを開いたとき、後ろのページがそのままスクロールしてしまう。
この挙動はよくある悩みのひとつです。

ユーザーから見ると「メニューを開いたのに背面が動く」のは違和感があり、操作性も下がります。
実際の案件でも、背景のスクロールを止めておくのはほぼ必須といえます。

ここでは、ハンバーガーメニュー展開時に背景をスクロールさせない方法を解説します。

完成品のデモ

まずは完成デモを確認してください。
メニューを開くと、背景のスクロールが止まり、メニュー内だけがスクロール可能になります。

See the Pen Drawer Templete by Suzuki Kazuma (@build_suzuki) on CodePen.

CodePenでは HTML / SCSS / TypeScript で構成していますが、
ダウンロードすれば HTML / CSS / JavaScript に変換されます。
プロジェクトに合わせて、お好きな方を使ってください。

スクロールを止める仕組み

ハンバーガーメニューを開いたときに背景を動かさない方法は、とてもシンプルです。

  • メニューを開いたときに、bodyoverflow: hiddenheight: 100% を付与する
  • メニューを閉じたときに、これらを元に戻す

これだけで、背面のスクロールを止められます。
メニュー自体には overflow: auto を指定してあるので、中身だけは通常どおりスクロールできます。

この仕組みを関数化したのが、lockScroll()unlockScroll() です。
フルコードの中では、メニューの開閉処理に組み込まれており、開いた瞬間にスクロールを止め、閉じたときに解除されるようになっています。

最小コード

背景スクロールを止めるだけなら、もっとシンプルに書けます。
以下のコードをコピペすれば、メニュー開閉と背景スクロール制御が最低限動作します。

document.addEventListener("DOMContentLoaded", () => {
  const button = document.querySelector(".drawer-button");
  const nav = document.querySelector(".drawer-nav");
  const root = document.documentElement;

  let isOpen = false;

  button.addEventListener("click", () => {
    isOpen = !isOpen;
    if (isOpen) {
      root.classList.add("is-open");
      nav.hidden = false;
      document.body.style.height = "100%";
      document.body.style.overflow = "hidden";
    } else {
      root.classList.remove("is-open");
      nav.hidden = true;
      document.body.style.height = "";
      document.body.style.overflow = "";
    }
  });
});
  • .drawer-button をクリックすると .drawer-nav が開閉します
  • 開いたときは bodyoverflow: hidden が付与され、背景のスクロールが止まります
  • 閉じると解除され、元の状態に戻ります

iOS Safari は挙動が異なる場合があるため、必ず実機で確認することをおすすめします。

まとめ

ハンバーガーメニューを開いたときに背景をスクロールさせない方法を紹介しました。

実装のポイントはシンプルで、

  • 開いたときに bodyoverflow: hidden; height: 100% を付与
  • 閉じたときに元へ戻す

これだけで、背景のスクロールを確実に止められます。

今回の内容を押さえておけば、ほとんどの案件で「背景が動いてしまう」という問題は解決できます。
もっと作り込んだハンバーガーメニューの完成版テンプレートも用意しているので、良かったらあわせてご覧ください。

使用サーバー

使用テーマ