ハンバーガーメニューとは
ハンバーガーメニューとは、横線を3本重ねた「≡」(三)のアイコンで表されるUIパーツのことです。 クリック(またはタップ)するとナビゲーションメニューが現れ、もう一度クリックすると閉じます。
スマートフォン向けに普及しましたが、現在はPC向けサイドバーの開閉トリガーとしても広く使われています。 このサイト自体もヘッダー左上の「三」ボタンで同じ仕組みを採用しています。
ナビゲーションのデモです
💡 このページで学ぶこと
HTML でボタンとドロワーを作り、CSS で見た目・アニメーションを付け、JavaScript で開閉を制御する。3つのコードをコピーするだけで、そのままページに組み込めます。
全体の仕組み
ハンバーガーメニューは、大きく3つのパーツで構成されます。
open クラスを付け外しするだけの超シンプルな制御開閉の仕組みは「クラスの付け外し」だけです。JavaScript が body に drawer-open クラスを追加すると、CSS が drawer をスライドインさせます。削除すると元に戻ります。
① HTML — ボタンとドロワーの骨格
最低限必要な要素は3つです。
ハンバーガーボタン
<button> の中に3本の <span> を並べます。CSS でこれを3本線に仕上げます。
ドロワー(スライドパネル)
画面端から現れるメニュー本体。<nav> タグを使うとアクセシビリティ上も適切です。
オーバーレイ(背景暗幕)
ドロワーの背後に透明な幕を敷きます。ここをクリックするとメニューが閉じます。
<!-- ① ハンバーガーボタン -->
<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のときドロワーをスライドインさせる- ボタンを押したとき「三→ ✕」に変形させるアニメーション
/* ── ハンバーガーボタン ── */
.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 の役割は非常にシンプルです。body に drawer-open クラスを付け外しするだけです。
// ドロワーを開く
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 を使います。
// ボタン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ファイル完結版です。「⊞ 全体を見る」を押すと小窓が開きます。
<!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" を付けると、スクリーンリーダーが状態を伝えられます。
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 を次のように変えます。
.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);
}
下からスライドアップ(モバイルシート)
スマートフォンでよく見るボトムシート型も同じ仕組みで実現できます。
.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 でクラスを付け外しするだけ — この構造さえ理解すれば、どんなデザインのドロワーにも応用できます。