この記事が解説すること
tailwindcss だけでハンバーガーニューを実装する方法を解説します。
本気で tailwindcss だけしか使えない環境の方はそんなにいないと思うのですが、でも tailwindcss だけで済むのだったらそれが何よりという方はいると思って書いていきます。
結論のコードはこれだ!
<header class="bg-teal-400 grid grid-cols-2 py-4 h-24">
<h1 class="text-2xl font-bold px-4">Hamburger Menu Sample</h1>
<div class="grid grid-cols-1 justify-items-end">
<div class="relative">
<input type="checkbox" class="peer opacity-0 size-8 z-50 fixed top-8 right-4" />
<svg xmlns="http://www.w3.org/2000/svg" class="peer-checked:hidden size-8 fixed top-8 right-4 z-0" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16" />
</svg>
<svg xmlns="http://www.w3.org/2000/svg" class="peer-checked:block hidden size-8 fixed top-8 right-4 z-0" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
</svg>
<nav class="fixed top-24 right-0 peer-checked:block hidden bg-teal-400 w-2/3 h-dvh">
<ul class="grid grid-cols-1 divide-y divide-white border-y border-white *:h-16 *:block">
<li class="p-2 content-center"><a href="#" class="block h-fit text-center">Home</a></li>
<li class="p-2 content-center"><a href="#" class="block h-fit text-center">About</a></li>
<li class="p-2 content-center"><a href="#" class="block h-fit text-center">Contact</a></li>
</ul>
</nav>
</div>
</div>
</header>
見た目はこうなる
closed | open |
---|---|
![]() |
![]() |
解説
やっていることは、 <input type="checkbox">
をopen/close ボタンの上に opacity-0
で透明にして配置し、チェックボックスにチェックが入っているときの表示を peer-checked:
を使って実装するってことをやってます。
なので、肝としては以下。
- チェックボックスとハンバーガーアイコン、クローズアイコンを綺麗に重ねる
- relative と fixed をうまく使おう
- その際、チェックボックスが一番上に来るように z-index を指定する
- チェックボックスには
class="peer opacity-0"
をつける - ハンバーガーアイコンとクローズアイコン、開きたいメニューの3つはチェックボックスの兄弟要素とする
- そうしないと、peer-checked: がうまく働きません
- 兄弟要素の構造を守っていれば、今回開きたいメニューとして実装した nav 要素は好きに書き換えて全然OK
- nav じゃなくて div を使ったりしても大丈夫
-
class="hidden peer-checked:block"
が一番肝心
という感じです。
まとめ
チェックボックスに opacity-0
を使う方法を見つけるまでに、だいぶ試行錯誤しました。
最初はチェクボックスを使う方法ではなく、アイコンをボタンにして focus が効いているかどうかでなんとかする方法を試みていて、 group-focus-within:
を使う方法でなんとかかんとかハンバーガーメニューを実装できた気がしたのですが、この group-focus は Safari および iOS ブラウザだと動かない!ということに気がつき、もっと確実な方法としてチェックボックスを透明にするというアイデアに辿り着いたのです。
ちなみに、同じ非表示でも sr-only とか hidden とか invisible とかはチェックボックスの機能が無効になってしまいます。
tailwindcss だけでハンバーガーメニューを実装してるのはだいぶ変だと思うのですが、前回の似たような記事でも書いた通り、tailwindcss だけで事が済むならそれがいいという環境の方はいらっしゃると思っているので、そういう方の一助になれば幸いです。