ハンバーガーメニューとは

ハンバーガーメニューとは、横線を3本重ねた「≡」(三)のアイコンで表されるUIパーツのことです。 クリック(またはタップ)するとナビゲーションメニューが現れ、もう一度クリックすると閉じます。

スマートフォン向けに普及しましたが、現在はPC向けサイドバーの開閉トリガーとしても広く使われています。 このサイト自体もヘッダー左上の「三」ボタンで同じ仕組みを採用しています。

▶ LIVE DEMO — ボタンをクリックしてみる

ナビゲーションのデモです

Menu
Home
About
Blog
Contact

💡 このページで学ぶこと

HTML でボタンとドロワーを作り、CSS で見た目・アニメーションを付け、JavaScript で開閉を制御する。3つのコードをコピーするだけで、そのままページに組み込めます。

全体の仕組み

ハンバーガーメニューは、大きく3つのパーツで構成されます。

🏗️
HTML
ボタン・オーバーレイ・ドロワーの3要素を定義する骨格
🎨
CSS
3本線の見た目、×アニメーション、スライドイン・フェードを定義
⚙️
JavaScript
クリック時に open クラスを付け外しするだけの超シンプルな制御

開閉の仕組みは「クラスの付け外し」だけです。JavaScript が bodydrawer-open クラスを追加すると、CSS が drawer をスライドインさせます。削除すると元に戻ります。

① HTML — ボタンとドロワーの骨格

最低限必要な要素は3つです。

1

ハンバーガーボタン

<button> の中に3本の <span> を並べます。CSS でこれを3本線に仕上げます。

2

ドロワー(スライドパネル)

画面端から現れるメニュー本体。<nav> タグを使うとアクセシビリティ上も適切です。

3

オーバーレイ(背景暗幕)

ドロワーの背後に透明な幕を敷きます。ここをクリックするとメニューが閉じます。

HTML
<!-- ① ハンバーガーボタン -->
<button class="menu-btn" onclick="openDrawer()" aria-label="メニューを開く">
  <span></span>
  <span></span>
  <span></span>
</button>

<!-- ② オーバーレイ(背景暗幕) -->
<div class="drawer-overlay" onclick="closeDrawer()"></div>

<!-- ③ ドロワー -->
<nav class="drawer" aria-label="サイトナビゲーション">
  <div class="drawer-head">
    <span>Menu</span>
    <button class="drawer-close" onclick="closeDrawer()">✕</button>
  </div>
  <ul>
    <li><a href="/">Home</a></li>
    <li><a href="/about">About</a></li>
    <li><a href="/blog">Blog</a></li>
    <li><a href="/contact">Contact</a></li>
  </ul>
</nav>

ポイントは aria-label 属性を付けることです。アイコンだけのボタンはスクリーンリーダーにとって意味不明になるため、必ずテキストで補足します。

② CSS — 見た目・アニメーション

CSS が担う役割は大きく3つあります。

  • 3本の <span> を「三」に見せる
  • body.drawer-open のときドロワーをスライドインさせる
  • ボタンを押したとき「三→ ✕」に変形させるアニメーション
CSS
/* ── ハンバーガーボタン ── */
.menu-btn {
  width: 40px;
  height: 40px;
  border: none;
  background: transparent;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  gap: 5px;
  padding: 6px;
  border-radius: 6px;
  transition: background 0.2s;
}
.menu-btn:hover {
  background: rgba(0, 0, 0, 0.06);
}
.menu-btn span {
  display: block;
  width: 22px;
  height: 2px;
  background: #1a1f2e;       /* ← 線の色 */
  border-radius: 2px;
  transition: transform 0.3s ease,
              opacity  0.3s ease,
              width    0.3s ease;
  transform-origin: center;
}

/* ── ×アニメーション(body に .drawer-open が付いたとき) ── */
body.drawer-open .menu-btn span:nth-child(1) {
  transform: translateY(7px) rotate(45deg);
}
body.drawer-open .menu-btn span:nth-child(2) {
  opacity: 0;
  width: 0;
}
body.drawer-open .menu-btn span:nth-child(3) {
  transform: translateY(-7px) rotate(-45deg);
}

/* ── オーバーレイ(背景暗幕) ── */
.drawer-overlay {
  display: none;
  position: fixed;
  inset: 0;                  /* top/right/bottom/left を一括指定 */
  background: rgba(0, 0, 0, 0.45);
  z-index: 900;
}
body.drawer-open .drawer-overlay {
  display: block;
}

/* ── ドロワー本体 ── */
.drawer {
  position: fixed;
  top: 0;
  left: 0;
  width: 280px;
  height: 100%;
  background: #ffffff;
  border-right: 1px solid #e4e7ed;
  z-index: 1000;
  transform: translateX(-100%);    /* 初期状態:画面外に隠す */
  transition: transform 0.3s ease;
  overflow-y: auto;
  padding: 0;
  list-style: none;
}
body.drawer-open .drawer {
  transform: translateX(0);        /* 開いたとき:スライドイン */
}

/* ── ドロワーヘッダー ── */
.drawer-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px 20px;
  border-bottom: 1px solid #e4e7ed;
  font-weight: 600;
}
.drawer-close {
  border: none;
  background: transparent;
  cursor: pointer;
  font-size: 1rem;
  color: #5a6478;
}

/* ── ドロワー内リスト ── */
.drawer ul {
  list-style: none;
  padding: 12px 0;
  margin: 0;
}
.drawer li a {
  display: block;
  padding: 10px 20px;
  color: #1a1f2e;
  text-decoration: none;
  font-size: 0.92rem;
  transition: background 0.15s;
}
.drawer li a:hover {
  background: #f7f8fa;
}

💡 transform: translateX(-100%) の意味

自分自身の幅100%分だけ左に移動する=画面外に隠れる、という指定です。ドロワーの幅が変わっても自動で対応するため、ピクセル指定より柔軟です。

③ JavaScript — 開閉ロジック

JavaScript の役割は非常にシンプルです。bodydrawer-open クラスを付け外しするだけです。

JavaScript
// ドロワーを開く
function openDrawer() {
  document.body.classList.add('drawer-open');
}

// ドロワーを閉じる
function closeDrawer() {
  document.body.classList.remove('drawer-open');
}

// Esc キーでも閉じられるようにする(UX向上)
document.addEventListener('keydown', function (e) {
  if (e.key === 'Escape') closeDrawer();
});

classList.add でクラスを追加し、classList.remove で削除します。 あとは CSS 側が body.drawer-open の状態を監視してアニメーションを担当するため、 JavaScript は「状態を変える」だけに専念できます。これがCSS と JavaScript の役割分離の基本形です。

トグルにしたい場合

ボタン1つで開閉を切り替えたいなら classList.toggle を使います。

JavaScript — toggle 版
// ボタン1つで開閉を切り替える
function toggleDrawer() {
  document.body.classList.toggle('drawer-open');
}

document.addEventListener('keydown', function (e) {
  if (e.key === 'Escape') {
    document.body.classList.remove('drawer-open');
  }
});

完全コード(コピペ用)

HTML・CSS・JavaScript をまとめた1ファイル完結版です。「⊞ 全体を見る」を押すと小窓が開きます。

HTML — 完全版(1ファイル)
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>ハンバーガーメニュー サンプル</title>
  <style>
    /* ── ハンバーガーボタン ── */
    .menu-btn {
      width: 40px; height: 40px;
      border: none; background: transparent; cursor: pointer;
      display: flex; flex-direction: column;
      justify-content: center; align-items: center;
      gap: 5px; padding: 6px; border-radius: 6px;
      transition: background 0.2s;
    }
    .menu-btn:hover { background: rgba(0,0,0,.06); }
    .menu-btn span {
      display: block; width: 22px; height: 2px;
      background: #1a1f2e; border-radius: 2px;
      transition: transform .3s ease, opacity .3s ease, width .3s ease;
      transform-origin: center;
    }
    /* ×アニメーション */
    body.drawer-open .menu-btn span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
    body.drawer-open .menu-btn span:nth-child(2) { opacity: 0; width: 0; }
    body.drawer-open .menu-btn span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

    /* ── オーバーレイ ── */
    .drawer-overlay {
      display: none; position: fixed; inset: 0;
      background: rgba(0,0,0,.45); z-index: 900;
    }
    body.drawer-open .drawer-overlay { display: block; }

    /* ── ドロワー ── */
    .drawer {
      position: fixed; top: 0; left: 0;
      width: 280px; height: 100%;
      background: #fff; border-right: 1px solid #e4e7ed;
      z-index: 1000; transform: translateX(-100%);
      transition: transform .3s ease; overflow-y: auto;
    }
    body.drawer-open .drawer { transform: translateX(0); }
    .drawer-head {
      display: flex; align-items: center;
      justify-content: space-between;
      padding: 16px 20px; border-bottom: 1px solid #e4e7ed; font-weight: 600;
    }
    .drawer-close { border: none; background: transparent; cursor: pointer; font-size: 1rem; color: #5a6478; }
    .drawer ul { list-style: none; padding: 12px 0; margin: 0; }
    .drawer li a {
      display: block; padding: 10px 20px;
      color: #1a1f2e; text-decoration: none;
      font-size: .92rem; transition: background .15s;
    }
    .drawer li a:hover { background: #f7f8fa; }

    /* ── ページレイアウト(サンプル用) ── */
    body { margin: 0; font-family: sans-serif; }
    header {
      display: flex; align-items: center; gap: 12px;
      padding: 0 16px; height: 56px;
      border-bottom: 1px solid #e4e7ed;
    }
    .site-name { font-weight: 700; font-size: 1rem; }
    main { max-width: 760px; margin: 40px auto; padding: 0 16px; }
  </style>
</head>
<body>

  <header>
    <!-- ① ハンバーガーボタン -->
    <button class="menu-btn" onclick="openDrawer()" aria-label="メニューを開く">
      <span></span><span></span><span></span>
    </button>
    <span class="site-name">MySite</span>
  </header>

  <!-- ② オーバーレイ -->
  <div class="drawer-overlay" onclick="closeDrawer()"></div>

  <!-- ③ ドロワー -->
  <nav class="drawer" aria-label="サイトナビゲーション">
    <div class="drawer-head">
      <span>Menu</span>
      <button class="drawer-close" onclick="closeDrawer()">✕</button>
    </div>
    <ul>
      <li><a href="/">Home</a></li>
      <li><a href="/about">About</a></li>
      <li><a href="/blog">Blog</a></li>
      <li><a href="/contact">Contact</a></li>
    </ul>
  </nav>

  <main>
    <h1>ページコンテンツ</h1>
    <p>左上の三ボタンをクリックしてみてください。</p>
  </main>

  <script>
    function openDrawer()  { document.body.classList.add('drawer-open'); }
    function closeDrawer() { document.body.classList.remove('drawer-open'); }
    document.addEventListener('keydown', function(e) {
      if (e.key === 'Escape') closeDrawer();
    });
  </script>

</body>
</html>

実装のポイントと応用

アクセシビリティへの配慮

ハンバーガーボタンは <div><span> で実装されることもありますが、<button> を使うと次のメリットがあります。

  • キーボード(Enter / Space キー)で操作できる
  • スクリーンリーダーが「ボタン」と読み上げる
  • onclick ハンドラが素直に動く

また、ドロワーが開いている間は aria-expanded="true" を付けると、スクリーンリーダーが状態を伝えられます。

JavaScript — aria-expanded 対応版
var menuBtn = document.querySelector('.menu-btn');

function openDrawer() {
  document.body.classList.add('drawer-open');
  menuBtn.setAttribute('aria-expanded', 'true');
}
function closeDrawer() {
  document.body.classList.remove('drawer-open');
  menuBtn.setAttribute('aria-expanded', 'false');
}

document.addEventListener('keydown', function (e) {
  if (e.key === 'Escape') closeDrawer();
});

右からスライドインさせる

ドロワーを画面右端から出したい場合は CSS を次のように変えます。

CSS — 右スライド版
.drawer {
  position: fixed;
  top: 0;
  right: 0;          /* ← left → right に変更 */
  left: auto;        /* ← left をリセット */
  width: 280px;
  height: 100%;
  background: #fff;
  border-left: 1px solid #e4e7ed;  /* ← border-right → border-left */
  z-index: 1000;
  transform: translateX(100%);     /* ← -100% → +100% */
  transition: transform .3s ease;
  overflow-y: auto;
}
body.drawer-open .drawer {
  transform: translateX(0);
}

下からスライドアップ(モバイルシート)

スマートフォンでよく見るボトムシート型も同じ仕組みで実現できます。

CSS — ボトムシート版
.drawer {
  position: fixed;
  bottom: 0;
  left: 0; right: 0;
  top: auto;               /* height指定に切り替え */
  width: 100%;
  max-height: 70vh;
  height: auto;
  background: #fff;
  border-top: 1px solid #e4e7ed;
  border-radius: 16px 16px 0 0;
  z-index: 1000;
  transform: translateY(110%);   /* 下に隠す */
  transition: transform .3s ease;
  overflow-y: auto;
}
body.drawer-open .drawer {
  transform: translateY(0);      /* 上にスライド */
}

🔑 まとめ:三ボタンの実装に必要なのはこの3点

<button> に3本の <span> を並べる / ② CSS で body.drawer-open を条件にアニメーションを定義する / ③ JavaScript でクラスを付け外しするだけ — この構造さえ理解すれば、どんなデザインのドロワーにも応用できます。