CSSだけでハンバーガーメニューを実装する方法|JavaScript不要のUIサンプル付き
HTMLとCSSだけで完結する、JavaScript不要のハンバーガーメニューの実装方法を紹介します。
チェックボックスと :checked 擬似クラスを利用することで、シンプルかつ軽量に開閉メニューを作ることができます。
実装の仕組み(checkbox + label)
今回の実装では、次のような仕組みを使います。
- チェックボックスを設置
- labelをクリックするとチェックが入る
:checkedを使ってメニューを表示する
:checked は「フォーム要素が選択状態のとき」に適用されるCSSの擬似クラスです。
- 未チェック → 非表示
- チェックあり → 表示
という制御をCSSで行います。
デモコード
See the Pen CSSだけでハンバーガーメニューの実装(checkbox + label) by mkl may (@mkl-may) on CodePen.
ポイントは以下の部分です。
|
1 2 |
<input type="checkbox" id="menu_toggle" class="menu_checkbox"> <label for="menu_toggle" class="hamburger_menu" aria-label="メニューを開く"> |
for属性で紐付けることで、labelクリック=チェックONになります。
ハンバーガーアイコン部分
HTML
|
1 2 3 4 5 |
<label for="menu_toggle" class="hamburger_menu" aria-label="メニューを開く"> <span class="hamburger_bar top"></span> <span class="hamburger_bar middle"></span> <span class="hamburger_bar bottom"></span> </label> |
3本線は span で作っています。
CSS
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
/* ハンバーガーアイコン */ /* 視覚的に非表示:アクセシビリティ対応 */ .menu_checkbox { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); border: 0; white-space: nowrap; } .hamburger_menu { position: fixed; top: 24px; right: 15px; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px; width: 56px; cursor: pointer; z-index: 200; background: none; border: none; padding: 0; } .hamburger_bar { display: block; width: 32px; height: 2px; background-color: #000; border-radius: 2px; transition: all 0.4s ease; } |
チェックボックスは画面上には表示せず、「状態を保持するためのトリガー」として利用しています。
バーの変形は transform を使用しています。
|
1 2 3 4 5 6 7 |
/* メニュー開閉時のバー変形 */ .menu_checkbox:checked + .hamburger_menu .hamburger_bar { background-color: #FFF; } .menu_checkbox:checked + .hamburger_menu .top {transform: translateY(10px) rotate(-45deg);} .menu_checkbox:checked + .hamburger_menu .middle {opacity: 0;} .menu_checkbox:checked + .hamburger_menu .bottom {transform: translateY(-10px) rotate(45deg);} |
translateY で上下位置を調整し、rotate で回転させることで「×」の形に変形させています。
これにより、
- 上下の線 → ×に変形
- 中央の線 → 非表示
という動きを作っています。
transitionを指定することで滑らかに変化します。
メニュー開閉部分
HTML
|
1 2 3 4 5 6 7 8 9 10 11 |
<div class="hamburger_open"> <div class="hamburger_open_box"> <div class="hamburger_open_menu"> <ul class="header_menu"> <li><a href="/">メニュー</a></li> <li><a href="/">メニュー</a></li> <li><a href="/">メニュー</a></li> </ul> </div> </div> </div> |
CSS
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
/* メニュー本体 */ .hamburger_open { position: fixed; inset: 0; background: #90959A; overflow-y: auto; -webkit-overflow-scrolling: touch; padding: 50px 15px 15px; opacity: 0; pointer-events: none; transition: all 0.3s ease; } /* チェックが入ったときに表示 */ .menu_checkbox:checked ~ .hamburger_open { opacity: 1; pointer-events: auto; } .hamburger_open * {text-align: left;} .hamburger_open_box { width: 100%; } .hamburger_open_menu {margin-bottom: 40px;} .header_menu { width: 100%; } .header_menu li a { display: block; padding-top: 1.6rem; padding-bottom: 1.6rem; border-bottom: 1px solid #E5E5E5; color: #FFF; } |
メニュー本体は「~(一般兄弟セレクタ)」を使用しています。
これは「同じ階層にある後続要素」を指定できるセレクタです。
|
1 |
.menu_checkbox:checked ~ .hamburger_open |
これにより、チェック時のみ
- opacity: 1
- pointer-events: auto
を適用しています。
display: none はアニメーションできないため、
opacity と pointer-events を使うことで自然なフェード演出を実現しています。
この実装のメリット・デメリット
メリット
- JavaScript不要
- 軽量
- 実装がシンプル
- 外部依存なし
デメリット
- aria-expanded などの状態制御ができない
- Escキーで閉じるなどの制御ができない
- フォーカス管理など、複雑な制御には向かない
- 状態が複雑になるとCSSだけでは管理が難しくなる
実務では「簡易メニュー」に向いています。
※ 本格的なUIやアクセシビリティ対応が必要な場合は、JavaScriptとの併用を検討しましょう。
まとめ
CSSだけでも、実用的なハンバーガーメニューは作れます。
JavaScriptを使わないことで、
- 実装が軽量になる
- 依存関係が減る
- トラブル要因を減らせる
といったメリットがあります。
軽量なサイトを作りたい場合は、ぜひ活用してみてください。
![MARKLEAPS[マークリープス]](https://markleaps.com/blog/wp-content/themes/mkl/images/00_logo.png)