【Next.js】アニメーションを使ったカッコいいヒーローセクションの作り方を解説
公開日: 2026年9月8日 · 読了目安 12 分
Next.js のファーストビューを、入場・スクロール・ホバーのあるヒーローにする方法を解説します。CSS、Framer Motion、完成セクションの流用の3通り。動きが地味になる理由と、公開前の失敗もまとめます。
先に結論:カッコいいヒーローは「何が動くか」で決まる
要約すると、Next.js のヒーローを今っぽく見せるには、大きな見出しより先に動きの設計が必要です。入場で要素が遅れて揃う、スクロールで背景や写真が追従する、ホバーで一点だけ反応する。この3つのどれかが見えると、同じ文言でもファーストビューの印象が変わります。
作り方は3つあります。CSSだけで入場を付ける。Framer Motion でスクロールに連動させる。すでに完成しているヒーローを自分のページに載せる。ゼロから全部書く必要はありません。
この記事を読み終える頃には、自分の LP に「動くヒーロー」を1本出せるようになります。
地味なヒーローに見える3つの理由
見出し、短い説明、ボタンが縦に並んでいるだけ。多くの Next.js のトップは、ここから始まります。悪い構成ではありません。ただ、画面を開いた瞬間に何も起きないと、写真つきの静的なバナーと同じに見えます。
1つ目は、全部が同時に出ることです。見出し・本文・CTA・画像が同じタイミングで揃うと、目線の順番がありません。人が「今っぽい」と感じるのは、要素が少しずつ揃うときです。
2つ目は、スクロールしてもヒーローが終わっていることです。100vh を過ぎた瞬間に次のセクションへ切れると、ファーストビューはポスターになります。背景がゆっくり追従する、画像が重なる、見出しが途中まで残る。こうした追従があると、ページ全体の導入になります。
3つ目は、動きを付けすぎることです。全要素が弾み、無限にループし、マウスを追うと、カッコよさより疲れが先に来ます。ヒーローで動かす箇所は、入場・スクロール・ホバーのうち2つまでにすると破綻しにくいです。
完成イメージ:この記事で作る動き
目指す動きは次のとおりです。
ページを開くと、小さなラベルが先に薄く現れ、続いて見出しが下から20pxほど上がる。本文とボタンはさらに0.1秒遅れる。右(または下)のビジュアルは、見出しより少し遅く、透明度だけが変わる。
少しスクロールすると、背景画像は本文より遅く上へ動く(パララックス)。CTA にカーソルを乗せると、背景色ではなく少しだけ縮尺が変わる。これだけでも、よくある「中央揃えの静的ヒーロー」とは別物に見えます。
独自の3Dやシェーダーは扱いません。まずは、LP の8割で効く入場とスクロールです。
作り方は3つある
同じ完成形でも、手数は分かれます。
方法1は CSS(と Tailwind)だけです。入場とホバーなら十分です。依存は増えません。スクロール連動は苦手です。
方法2は Framer Motion です。表示領域に入ったとき、スクロール量に応じた変化が書きやすいです。代わりに "use client" とパッケージが必要です。
方法3は、動きまで組んであるヒーローを自分のアプリに載せる方法です。タイミングを一から決めなくて済みます。見出しと写真の差し替えが仕事になります。演出を1pxまで自前で決めたい場合は向きません。
迷ったら、まず方法1で入場だけ付けて公開し、物足りなければ方法2か3に進むのが早いです。
方法1:CSSだけで入場を付ける
サーバーコンポーネントのまま始められます。keyframes で「下からフェードイン」を1つ作り、見出しと本文にだけ delay をずらします。
ポイントは遅延だけずらすこと
全部に同じ animation を付けると、同時に出る静的ヒーローと大差ありません。ラベル 0秒、見出し 0.08秒、本文 0.16秒、ボタン 0.24秒、くらいの段差で足ります。距離は 16〜24px。大きく飛ばすとチープに見えます。
@keyframes hero-rise {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.hero-rise {
animation: hero-rise 0.7s ease-out both;
}Next.js の page に載せる
App Router なら、ヒーローは page.tsx の先頭に置きます。ボタンのホバーは scale を少しだけ。影を強くしたり色を点滅させたりしない方が、入場と喧嘩しません。
export default function Page() {
return (
<section className="min-h-[100svh] px-6 pt-28">
<p className="hero-rise text-sm tracking-wide">2026 Launch</p>
<h1 className="hero-rise mt-4 text-4xl font-semibold" style={{ animationDelay: "80ms" }}>
動きのあるファーストビューを、今日出す
</h1>
<p className="hero-rise mt-5 max-w-xl text-zinc-600" style={{ animationDelay: "160ms" }}>
見出し、本文、ボタンの順に揃えるだけで印象は変わります。
</p>
<a className="hero-rise mt-8 inline-flex rounded-full bg-zinc-950 px-5 py-3 text-white transition hover:scale-[0.98]" style={{ animationDelay: "240ms" }}>
詳しく見る
</a>
</section>
);
}方法2:Framer Motion でスクロールに連動させる
入場だけなら CSS で足りることが多いです。スクロール量に応じて位置や透明度を変えたいとき、Framer Motion が向きます。
Next.js では、useScroll や motion を使うファイルの先頭に "use client" が必要です。ページ全体をクライアントコンポーネントにせず、ヒーローだけ切り出します。
表示されたら一度だけ入場する
whileInView は、スクロールして戻るたびに繰り返さない方がヒーローらしいです。once: true を付けます。弱い指定は animate だけ(マウントと同時)。強い指定は初期位置・イージング・遅延を要素ごとに分けることです。
"use client";
import { motion } from "framer-motion";
const rise = {
hidden: { opacity: 0, y: 20 },
show: { opacity: 1, y: 0 },
};
export function Hero() {
return (
<section className="min-h-[100svh] px-6 pt-28">
<motion.h1
variants={rise}
initial="hidden"
whileInView="show"
viewport={{ once: true, amount: 0.6 }}
transition={{ duration: 0.7, ease: [0.22, 1, 0.36, 1] }}
className="text-4xl font-semibold"
>
スクロールした瞬間に、見出しが揃う
</motion.h1>
</section>
);
}弱い動きと強い動き
弱い例は、duration を 1.4秒以上にして bounce を使うことです。LP のヒーローは商品紹介であり、ローディング画面ではありません。
強い例は、イージングを少し減速寄りにし、画像だけ 0.12秒遅らせることです。テキストが先、ビジュアルが後。雑誌の見開きに近い順番になります。
パララックスを足すなら、背景だけ useScroll で数パーセント動かします。全面を追従させると文字が読みにくくなります。
方法3:完成しているヒーローを載せる
スクロールで草木の後ろから見出しが出る、最初の2秒でロゴが抜ける、写真がピンされたまま切り替わる。こうした塊は、方法1と2を組み合わせても半日かかることがあります。
その場合は、ブラウザで実際の動きを見てから、React と Tailwind でできたヒーローを自分の Next.js に載せる方法があります。DesignLayer のカタログは、その置き場です。閲覧にカードは不要です。https://design-layer.com/components
向き不向きを先に言います。世界観の演出を先に決めたい、タイミングを自分でチューニングしたくない、既存の shadcn のページにセクションを足したい、というときに向きます。デザインシステムの色を1pxまで合わせたい、ヒーロー自体がプロダクトの核、というときには方法2の方が制御できます。
載せるときの仕事は3つです。ライブでスクロールして「この動きでいいか」を決める。ソースを自分のリポジトリに置く。見出し・CTA・画像だけ差し替える。余白やイージングから作り直す必要はありません。
無料のソースコピーは日本時間で1日1回です。今日ヒーロー1本、で足ります。完成した1ページをまるごと使いたい場合は Templates です。
公開前チェックリスト
動きが付いたあとに見るのは、次の5点です。
1. prefers-reduced-motion で入場を切れるか。OS の設定を尊重します。
2. モバイルでファーストビューに、見出しと CTA が入るか。アニメーションの開始位置が画面外だと、何も起きていないように見えます。
3. LCP の画像をアニメーションで透明にしたままにしていないか。最初の写真は最初から見えていた方が、体感も計測も安定します。
4. ヒーロー以外に同じ強さの動きを並べていないか。次のセクションは静止、または薄いフェードで十分です。
5. "use client" を page.tsx 全体に書いていないか。ヒーローだけクライアントに切り出します。
よくある失敗
失敗1:全部を同時に animate する。方法1の delay を忘れている状態です。段差がない動きは、動いていないのと同じに見えます。
失敗2:動画を黙って自動再生する。音が出ると離脱します。poster 画像なしだと、読み込み中が黒になります。動画ヒーローが必要かは、別の判断です。まずは静止画+入場で足りることが多いです。
失敗3:何が動くかを決めないままライブラリを足すこと。「カッコよく」だけでは、パーティクルとグラデーションが同時に来ます。入場・スクロール・ホバーのどれを付けるかを先に決めてください。
よくある質問
実装で繰り返し出る質問です。
Next.js のヒーローにアニメーションを付けるには何が必要ですか?
入場とホバーだけなら CSS で足ります。スクロール量に応じた変化が要るなら Framer Motion か GSAP です。ページ全体をクライアントコンポーネントにする必要はありません。
サーバーコンポーネントのままヒーローを動かせますか?
CSS アニメーションなら可能です。useScroll やマウス座標を使うなら、ヒーロー用のファイルだけ "use client" にします。
Framer Motion は必須ですか?
必須ではありません。多くの LP は CSS の入場で十分です。スクロール連動、共有レイアウト、ドラッグが必要になってから入れてください。
スマホで動きが重いときは?
ぼかし、大きな固定背景、同時に動く要素の数を先に減らします。filter: blur と box-shadow のアニメーションは特に高いです。transform と opacity だけにすると安定します。
アクセシビリティはどうしますか?
prefers-reduced-motion: reduce のとき、入場を切るか、フェードだけにします。情報は動きに依存させない。見出しと CTA は、アニメーションが無くても読めます。
動画ヒーローと CSS アニメーション、どちらがカッコいいですか?
映像そのものが商品なら動画です。製品やサービスの LP なら、短い入場の方が CTA が埋もれません。尺は 15〜30秒、字幕、poster が揃っていない動画は、静的ヒーローより弱くなることがあります。
完成しているヒーローを使うときの注意は?
動きは触らず、文章と画像だけ変える方が崩れません。色を既存トークンに寄せるのはそのあとです。全セクションに同じ強さのヒーローを並べないでください。
既存の page.tsx のどこに置けばよいですか?
ヘッダーの下、最初の <section> です。min-h-[100svh] を付けるとファーストビューが安定します。モバイルブラウザのアドレスバー対策には 100vh より 100svh が向きます。