【Next.js】ハンバーガーメニューのアニメーション実装
公開日: 2026年9月12日 · 読了目安 9 分
Next.js でモバイルナビを開閉する手順。フォーカス閉じ込め、スクロールロック、オーバーレイの入場。完成ヘッダーを載せる判断も解説します。
先に結論:見た目より、閉じられることが先
ハンバーガーのアニメーションは、線がバツになる、パネルが右から出る、背景が暗くなる、の3点で十分です。先に必要なのは Escape で閉じる、フォーカスがパネル内に残る、背景がスクロールしない、です。
page.tsx はサーバーのまま、ヘッダーだけ "use client" にします。
作り方は3つです。CSS の開閉。Radix / vaul などのプリミティブ。完成しているナビを載せる。
使いにくいメニューになる3つの理由
1つ目は、開いたまま背面がスクロールすることです。body の overflow を開閉に合わせて切ります。
2つ目は、フォーカスが背面のリンクに逃げることです。
3つ目は、閉じる手段がハンバーガー再タップだけのことです。オーバーレイタップと Escape を足します。
方法1:状態と CSS で開閉する
useState で open を持ち、パネルに translate と opacity を付けます。ボタンには aria-expanded と aria-controls を付けます。
最小の開閉
"use client";
import { useState } from "react";
export function MobileNav() {
const [open, setOpen] = useState(false);
return (
<div className="md:hidden">
<button
type="button"
aria-expanded={open}
onClick={() => setOpen((v) => !v)}
>
メニュー
</button>
{open ? (
<nav className="fixed inset-0 z-50 bg-zinc-950/95 p-6">
<a href="#pricing">料金</a>
</nav>
) : null}
</div>
);
}方法2:プリミティブに任せる
フォーカス閉じ込めとスクロールロックまで自分で書くと漏れます。Dialog 系のプリミティブを使うと、アニメーションだけ足せば足ります。
shadcn/ui の Sheet は、この用途に近いです。見た目の署名は、完成ナビの方が強いです。
方法3:完成しているヘッダーを載せる
デスクトップは透明の固定、モバイルはフルスクリーンの開閉、という塊は、ヘッダー記事の方法2とこの記事を足しても時間がかかります。
DesignLayer でライブプレビューし、リンクだけ差し替えてください。ヘッダー全体の解説は https://design-layer.com/articles/nextjs-modern-header-guide です。
無料コピーは1日3回です。ナビとヒーローを同じ日に取るなら、枠を計画してください。
公開前チェックリスト
1. Escape で閉じるか。2. 開いているとき背面がスクロールしないか。3. フォーカスリングが見えるか。4. md 以上でハンバーガーが消えるか。5. 動きを reduced-motion で弱められるか。