CSSモジュールとグローバルスタイル

Next.jsは以下の種類のスタイルシートをサポートしています:

CSSモジュール

Next.jsは.module.css拡張子を使用したCSSモジュールを組み込みでサポートしています。

CSSモジュールは、自動的に一意のクラス名を生成することでCSSをローカルスコープ化します。これにより、異なるファイルで同じクラス名を使用しても衝突を心配する必要がありません。この動作により、CSSモジュールはコンポーネントレベルのCSSを含める理想的な方法となっています。

CSSモジュールはappディレクトリ内の任意のファイルにインポートできます:

import styles from './styles.module.css'

export default function DashboardLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return <section className={styles.dashboard}>{children}</section>
}
import styles from './styles.module.css'

export default function DashboardLayout({ children }) {
  return <section className={styles.dashboard}>{children}</section>
}
app/dashboard/styles.module.css
.dashboard {
  padding: 24px;
}

CSSモジュールは .module.css.module.sass拡張子のファイルに対してのみ有効 です。

本番環境では、すべてのCSSモジュールファイルは自動的に 多くの最小化されコード分割された .cssファイルに結合されます。 これらの.cssファイルはアプリケーション内のホットな実行パスを表しており、アプリケーションの描画に必要な最小限のCSSが読み込まれることを保証します。

グローバルスタイル

グローバルスタイルはappディレクトリ内の任意のレイアウト、ページ、またはコンポーネントにインポートできます。

知っておくと良い: これはpagesディレクトリとは異なり、_app.jsファイル内でのみグローバルスタイルをインポートできる仕様です。

例えば、app/global.cssという名前のスタイルシートを考えてみましょう:

body {
  padding: 20px 20px 60px;
  max-width: 680px;
  margin: 0 auto;
}

ルートレイアウト(app/layout.js)内でglobal.cssスタイルシートをインポートすると、アプリケーションのすべてのルートにスタイルが適用されます:

// これらのスタイルはアプリケーションのすべてのルートに適用されます
import './global.css'

export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html lang="en">
      <body>{children}</body>
    </html>
  )
}
// これらのスタイルはアプリケーションのすべてのルートに適用されます
import './global.css'

export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body>{children}</body>
    </html>
  )
}

外部スタイルシート

外部パッケージによって公開されたスタイルシートは、同梱されたコンポーネントを含むappディレクトリ内のどこにでもインポートできます:

import 'bootstrap/dist/css/bootstrap.css'

export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html lang="en">
      <body className="container">{children}</body>
    </html>
  )
}
import 'bootstrap/dist/css/bootstrap.css'

export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body className="container">{children}</body>
    </html>
  )
}

知っておくと良い: 外部スタイルシートはnpmパッケージから直接インポートするか、ダウンロードしてコードベースと同梱する必要があります。<link rel="stylesheet" />は使用できません。

順序と結合

Next.jsは本番ビルド時にCSSを最適化し、スタイルシートを自動的にチャンク(結合)します。CSSの順序は、アプリケーションコードにスタイルシートをインポートした順序によって決定されます。

例えば、base-button.module.csspage.module.cssよりも前に順序付けられます。なぜなら<BaseButton><Page>内で最初にインポートされているからです:

import styles from './base-button.module.css'

export function BaseButton() {
  return <button className={styles.primary} />
}
import styles from './base-button.module.css'

export function BaseButton() {
  return <button className={styles.primary} />
}
import { BaseButton } from './base-button'
import styles from './page.module.css'

export function Page() {
  return <BaseButton className={styles.primary} />
}
import { BaseButton } from './base-button'
import styles from './page.module.css'

export function Page() {
  return <BaseButton className={styles.primary} />
}

予測可能な順序を維持するために、以下を推奨します:

  • 1つのJS/TSファイルにのみCSSファイルをインポートする
    • グローバルクラス名を使用する場合、適用したい順序で同じファイルにグローバルスタイルをインポートする
  • グローバルスタイルよりもCSSモジュールを優先する
    • CSSモジュールに一貫した命名規則を使用する。例えば、<name>.tsxよりも<name>.module.cssを使用する
  • 共有スタイルを別の共有コンポーネントに抽出する
  • Tailwindを使用する場合、ファイルの先頭、できればルートレイアウトでスタイルシートをインポートする

知っておくと良い: 開発モードではCSSの順序は異なる動作をするため、本番ビルドでの最終的なCSS順序を確認するためにプレビューデプロイメントを常に確認してください。

追加機能

Next.jsにはスタイルの追加体験を向上させるための追加機能が含まれています:

  • next devでローカル実行する場合、ローカルスタイルシート(グローバルまたはCSSモジュール)はFast Refreshを活用し、編集が保存されると即座に変更が反映されます。
  • next buildで本番ビルドする場合、CSSファイルはスタイルを取得するために必要なネットワークリクエストの数を減らすために、より少ない最小化された.cssファイルにバンドルされます。
  • JavaScriptを無効にしても、本番ビルド(next start)ではスタイルが読み込まれます。ただし、next devFast Refreshを有効にするにはJavaScriptが必要です。