【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。大きく飛ばすとチープに見えます。

app/globals.css
@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 を少しだけ。影を強くしたり色を点滅させたりしない方が、入場と喧嘩しません。

app/page.tsx
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 だけ(マウントと同時)。強い指定は初期位置・イージング・遅延を要素ごとに分けることです。

components/Hero.tsx
"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 が向きます。

【Next.js】アニメーションを使ったカッコいいヒーローセクションの作り方を解説 | DesignLayer