【Next.js】ベントグリッドの作り方を Tailwind CSS のコード付きで解説

公開日: 2026年9月12日 · 読了目安 10 分

Next.js でベントグリッド(Bento UI)を作る手順をコード付きで解説。Tailwind CSS の col-span・row-span でマスの比率を決め、スマホでは1列に戻し、大きいマスだけをゆっくり動かす方法まで扱います。

ベントグリッドは CSS Grid と大きいマス1つで作れる

Apple の発表スライドのような、大小のマスを組み合わせたレイアウトを Next.js の LP に入れたい。試しにカードを並べてみたら、ただのタイル一覧に見えた。

そんなときに読んでほしい記事です。

ベントグリッド(Bento UI)は、弁当箱のように大きさの違うマスを1つの枠に収めるレイアウトです。

CSS Grid の基本の指定だけで作れるので、専用のライブラリは要りません。

コツは、大きいマスを1つだけ決め、残りをその補足にすることです。

この記事で分かること:

  • Tailwind CSS の grid でベントグリッドを組むコード

  • 4列・2列・1列と、画面幅に合わせてマスを組み替える方法

  • 大きいマスだけをループで動かし、他は入場だけにする方法

  • 見出しの順番・キーボード操作・表示速度で気をつけること

ベントグリッドが崩れて見える3つの理由

ベントグリッドは、うまくいくと情報量が多くても整って見えます。一方で、少し外すと「カードを詰め込んだだけ」に見えます。

崩れて見える原因は、たいてい次のどれかです。

  • 全部のマスが同じ大きさか、大きいマスが2つ以上あって、どこを見ればよいか分からない

  • 大きいマスに長い文章を詰めている(大きいマスは写真か数字の場所)

  • スマホでもデスクトップと同じスパンを使い、細いマスが縦に伸びる

加えて、全部のマスに枠線と影を付けると、画面が重くなります。マスの区切りは、余白と背景の色の差だけで十分です。

Tailwind CSS の grid でベントグリッドを組む

まず、デスクトップでのマスの配置を決めます。ここでは4列2行の枠に、次の4つのマスを置きます。

  • 目玉のマス: 2列×2行(左半分)。写真と短い見出しを置く

  • 数字のマス2つ: 1列×1行(右上に2つ並ぶ)

  • 横長のマス: 2列×1行(右下)。補足の説明や小さなデモを置く

この配置を Tailwind CSS のクラスにすると、次のコードになります。

状態を持たないので、サーバーコンポーネントのまま使えます。

components/Bento.tsx
import Image from "next/image";

  export function Bento() {
    return (
      <section className="mx-auto max-w-6xl px-6 py-24">
        <h2 className="text-3xl font-semibold tracking-tight md:text-4xl">
          チームの仕事が、ひと目で分かる
        </h2>

        <div className="mt-12 grid auto-rows-[minmax(180px,auto)] grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4">
          <article className="relative overflow-hidden rounded-3xl bg-zinc-900 p-8 text-white sm:col-span-2 lg:row-span-2">
            <Image
              src="/bento/team.jpg"
              alt="打ち合わせをするチーム"
              fill
              sizes="(min-width: 1024px) 50vw, 100vw"
              className="object-cover opacity-60"
            />
            <div className="relative flex h-full flex-col justify-end">
              <h3 className="text-2xl font-semibold">進み具合を1画面で共有</h3>
              <p className="mt-2 max-w-sm text-sm text-zinc-200">
                誰が何をしているか、会議を開かずに分かります。
              </p>
            </div>
          </article>

          <article className="rounded-3xl bg-zinc-100 p-6">
            <p className="text-4xl font-semibold">98%</p>
            <h3 className="mt-2 text-sm text-zinc-600">翌月も使い続けるチームの割合</h3>
          </article>

          <article className="rounded-3xl bg-zinc-100 p-6">
            <p className="text-4xl font-semibold">3分</p>
            <h3 className="mt-2 text-sm text-zinc-600">導入にかかる平均時間</h3>
          </article>

          <article className="rounded-3xl bg-indigo-50 p-6 sm:col-span-2">
            <h3 className="font-semibold">Slack と GitHub につながる</h3>
            <p className="mt-2 text-sm text-zinc-600">
              通知はいつものチャンネルに届き、新しいツールを開く必要がありません。
            </p>
          </article>
        </div>
      </section>
    );
  }

ベントグリッドの行の高さを揃える

列の数(grid-cols)を決めたら、次は行の高さ(auto-rows)を決めます。

コードでは、行の高さを「最低 180 ピクセル、中身が多ければ伸びる」と指定しています。

高さを固定しないので、文章が増えてもマスからはみ出しません。

row-span-2 のマスは、2行分の高さと gap を足した大きさになります。目玉のマスを写真で埋めるなら、この高さがあると見栄えがよくなります。

マスの間の溝は 16〜24px にする

ベントグリッドは、マスの間の溝が均一であることで整って見えます。gap-4(16px)から gap-6(24px)が扱いやすい幅です。

角丸は rounded-2xl から rounded-3xl くらいにし、全部のマスで揃えます。

ベントグリッドの空いたマスを自動で詰める

マスの数や大きさを変えて穴が空いたときは、grid-flow-row-dense を付けると、後ろのマスが空きに詰められます。

ただし、見た目の順番と HTML の順番がずれるため、Tab キーでの移動順が飛びます。

まずはマスの順番を書き換えて解決し、それでも難しいときだけ使います。

スマホではベントグリッドを1列か2列に戻す

デスクトップと同じ col-span をスマホにも当てると、細いマスが縦に長く伸びて読みにくくなります。上のコードでは、ブレークポイントごとに列の数を変えています。

  • スマホ(sm 未満): 1列。全部のマスが縦に並ぶ

  • タブレット(sm 以上): 2列。目玉と横長のマスは2列をまたぐ

  • デスクトップ(lg 以上): 4列。目玉のマスが2行をまたぐ

スパンのクラスに sm: や lg: を付けているのは、この切り替えのためです。row-span-2 も lg: のときだけ効かせると、スマホで目玉のマスが不自然に高くなりません。

1列のときは、目玉のマスを最初に置くと、写真から読み始められます。

ベントグリッドの大きいマスだけを動かすアニメーション

ベントグリッドに動きを付けるときは、役割を分けます。大きいマスの中だけゆっくりループする背景を置き、小さいマスは入場のときに少しずつ遅れて出るだけにします。

全部のマスが同時に浮いたり揺れたりすると、グリッドの形が見えなくなります。

目玉のマスにループするグラデーションを敷く

CSS の keyframes を globals.css に1つ足し、Tailwind CSS の任意値クラスで呼び出します。12 秒かけて往復する程度の遅さにすると、背景として目にうるさくなりません。

app/globals.css
@keyframes bento-drift {
    0%,
    100% {
      transform: translate(0, 0) scale(1);
    }
    50% {
      transform: translate(-6%, 4%) scale(1.1);
    }
  }

目玉のマスに置くグラデーションの要素

目玉のマスの中、写真の代わりか写真の上に置きます。マスに overflow-hidden が付いているので、はみ出した部分は見えません。

components/Bento.tsx(目玉のマスの中)
<div
    aria-hidden
    className="absolute -inset-1/4 bg-[radial-gradient(circle_at_30%_30%,#6366f1,transparent_60%)] opacity-70 animate-[bento-drift_12s_ease-in-out_infinite] motion-reduce:animate-none"
  />

小さいマスは入場のタイミングだけ遅らせる

Motion(旧 Framer Motion)の whileInView(画面に入ったら動かす指定)で、マスごとに 0.06 秒ずつ遅らせて出します。

マスの article をこの BentoTile に置き換え、何番目のマスか(index)を渡します。

components/BentoTile.tsx
"use client";

  import { motion } from "motion/react";
  import type { ReactNode } from "react";

  export function BentoTile({
    index,
    className,
    children,
  }: {
    index: number;
    className?: string;
    children: ReactNode;
  }) {
    return (
      <motion.article
        className={className}
        initial={{ opacity: 0, y: 20 }}
        whileInView={{ opacity: 1, y: 0 }}
        viewport={{ once: true, amount: 0.4 }}
        transition={{ duration: 0.5, delay: index * 0.06, ease: "easeOut" }}
      >
        {children}
      </motion.article>
    );
  }

ベントグリッドを公開する前の確認リスト

ベントグリッドは見た目が先に立つため、次の点を見落としがちです。公開前に1つずつ確かめてください。

  • 見出しの順番: マスの見出しは同じ階層(h3)に揃え、階層を飛ばさない

  • キーボード: マスにリンクがあるとき、Tab キーでの移動順が見た目の順番と大きくずれない

  • 表示速度: 最初の画面にあるなら、目玉の写真に優先読み込み(priority)を付け、そのマスを透明から始めない

  • スマホ: 1列で縦に並べたとき、目玉のマスが最初に来る

  • 動きを減らす設定: その設定の人には、ループを止めている

完成したベントグリッドをコピーして使う方法

DesignLayer の「製品機能ベントー」の詳細ページ。左でライブプレビューを確かめ、右の「Cursor 用にコピー」でソースをコピーできる
DesignLayer の「製品機能ベントー」の詳細ページ。左でライブプレビューを確かめ、右の「Cursor 用にコピー」でソースをコピーできる

次の要素まで揃ったベントグリッドは、grid のクラスだけでは決まりません。調整に半日かかることもあります。

  • マスの比率

  • 角丸

  • 中の文字の大きさ

  • 目玉のマスのループ

DesignLayer は、人が組んだ React + Tailwind のモーション付きセクションを、ブラウザでライブプレビューしてからコピーできるカタログです。

閲覧はアカウントもカードも不要です。https://design-layer.com/ja/components

無料サンプル10個を無料アカウントで回数制限なくコピーでき、動画プロンプトは月1回です。Free では MCP に接続できません。カタログ全体は30日ビルドパス($19の1回払い、自動更新なし)、Lifetime Access(先着100名の$79の1回払い)、Plus(月額 $9、いつでも解約可)です。コピーした後は、目玉のマスの写真と数字の文言だけを差し替えます。

マスの比率は触らない方が崩れません。

ベントグリッドについてよくある質問

  • 必要ありません。CSS Grid の列の指定(grid-template-columns)と、マスをまたがせる指定(span)で作れます。

    Tailwind CSS なら、4種類のクラスで足ります。列の数と行の高さは、grid-cols と auto-rows で決めます。

    マスの大きさは、何列・何行をまたぐか(col-span と row-span)で決めます。

まとめ:Next.js でベントグリッドを作る手順

  • ベントグリッドは CSS Grid の基本の指定だけで作れる

  • 大きいマスは1つだけにし、写真か数字を置く

  • スマホでは1列、タブレットでは2列に戻し、目玉のマスを2行分にするのはデスクトップだけにする

  • 動きは大きいマスのループと、小さいマスの入場の遅延に分ける

  • 見出しの順番・キーボードでの移動順・目玉の写真の読み込みを公開前に確認する

まずはこの記事の Bento をそのまま貼り、写真と数字を自分の内容に差し替えてみてください。

カードで見せる場合は https://design-layer.com/ja/articles/nextjs-features-section-guide 、Tailwind CSS での動きの付け方は https://design-layer.com/ja/articles/nextjs-tailwind-animation-guide が参考になります。

関連ガイド