コンテンツにスキップ

Chapter 2: CSSとスタイリング

Chapter 1 で立ち上げた App Router プロジェクトはまだ素の状態です。ここでは Next.js でよく使われるスタイリング手法を整理し,実際に画面へ反映していきます。


この章で身につくこと

  • グローバル CSS をルートレイアウトへ適用する流れを理解する
  • Tailwind CSS と CSS Modules を組み合わせて使い分ける
  • clsx を使った条件付きクラスの切り替えパターンを学ぶ

グローバルスタイルを読み解く

/app/ui/global.css には,リセットや共通タイポグラフィを含むグローバルスタイルが定義されています。App Router ではルートレイアウト (/app/layout.tsx) にインポートするのが定石です。

/app/layout.tsx
import '@/app/ui/global.css';

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body>{children}</body>
    </html>
  );
}

保存するとホームページにスタイルが付きます。

alt text

CSS を書き足していないのに整った見た目になるのは global.css に Tailwind のベースクラスが含まれているためです。

/app/ui/global.css
@tailwind base;
@tailwind components;
@tailwind utilities;

Tailwind CSS を使ってみる

Tailwind はユーティリティクラスを組み合わせて UI を構築するフレームワークです。create-next-app のセットアップ時に Tailwind を有効にすると,自動的に必要な依存が追加されます。

/app/page.tsx にはすでに Tailwind のクラスが書かれています。

/app/page.tsx
import AcmeLogo from '@/app/ui/acme-logo';
import { ArrowRightIcon } from '@heroicons/react/24/outline';
import Link from 'next/link';

export default function Page() {
  return (
    <main className="flex min-h-screen flex-col p-6">
      <div className="flex h-20 shrink-0 items-end rounded-lg bg-blue-500 p-4 md:h-52">
        {/* ... */}
      </div>
    </main>
  );
}

クラス名を直接書き換えるだけで見た目が変わる点が特徴です。以下を <p> 要素の直前に追加して,Tailwind の書き味を試してみましょう。

/app/page.tsx
<div
  className="relative h-0 w-0 border-l-[15px] border-r-[15px] border-b-[26px] border-l-transparent border-r-transparent border-b-black"
/>

CSS Modules でスタイルを分ける

Tailwind だけでなく,従来の CSS ファイルを分けて管理したい場面もあります。Next.js では CSS Modules を使うと,クラス名を自動でユニークにしながらコンポーネント単位でスタイルを切り出せます。

/app/ui/home.module.css を作成して次を記述します。

/app/ui/home.module.css
.shape {
  height: 0;
  width: 0;
  border-bottom: 30px solid black;
  border-left: 20px solid transparent;
  border-right: 20px solid transparent;
}

そのうえで /app/page.tsx を読み込むよう更新します。

/app/page.tsx
import AcmeLogo from '@/app/ui/acme-logo';
import { ArrowRightIcon } from '@heroicons/react/24/outline';
import Link from 'next/link';
import styles from '@/app/ui/home.module.css';

export default function Page() {
  return (
    <main className="flex min-h-screen flex-col p-6">
      <div className={styles.shape} />
      {/* ... */}
    </main>
  );
}

Tailwind のクラスを削除して styles.shape に置き換えても,同じ三角形が描画されるはずです。ユーティリティクラスと CSS Modules は共存できるので,場面に応じて組み合わせましょう。


clsx で条件付きクラスを切り替える

状態に応じてクラスを出し分けるときは clsx が便利です。例えば請求書のステータスを表示するコンポーネントは次のように書けます。

/app/ui/invoices/status.tsx
import clsx from 'clsx';

export default function InvoiceStatus({ status }: { status: string }) {
  return (
    <span
      className={clsx(
        'inline-flex items-center rounded-full px-2 py-1 text-sm',
        {
          'bg-gray-100 text-gray-500': status === 'pending',
          'bg-green-500 text-white': status === 'paid',
        },
      )}
    >
      {/* ... */}
    </span>
  );
}

オブジェクト形式でクラスを渡すと,真偽値によって自動的に付け外しされます。Tailwind のユーティリティクラスとも相性が良いので,複雑な条件分岐を避けたいときに活用しましょう。


他のスタイリング手法

Next.js ではほかにも Sassstyled-components / emotion などの CSS-in-JS を利用できます。用途やチームの合意に合わせて選択してください。詳細は Next.js のスタイリングガイド も参照しましょう。

次章ではフォントと画像の最適化に進み,デザインをさらに整えていきます。