Menu

CSS

Next.jsは以下を含む複数のCSS処理方法をサポートしています:

CSSモジュール

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

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

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

app/dashboard/layout.tsx
TypeScript
import styles from './styles.module.css'
 
export default function DashboardLayout({
  children,
}: {
  children: React.ReactNode
}) {
  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ディレクトリとは異なります。pagesディレクトリでは_app.jsファイル内でのみグローバルスタイルをインポートできます。
  • Next.jsは、実際にグローバルであるスタイル(つまり、すべてのページに適用でき、アプリケーションの存続期間中維持できるスタイル)以外のグローバルスタイルの使用をサポートしていません。これは、Next.jsがSuspenseと統合するためにReactの組み込みスタイルシートサポートを使用しているためです。この組み込みサポートは現在、ルート間のナビゲーション時にスタイルシートを削除しません。このため、グローバルスタイルよりもCSSモジュールの使用をお勧めします。

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

app/global.css
body {
  padding: 20px 20px 60px;
  max-width: 680px;
  margin: 0 auto;
}

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

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

外部スタイルシート

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

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

補足: 外部スタイルシートはnpmパッケージから直接インポートするか、ダウンロードしてコードベースと一緒に配置する必要があります。<link rel="stylesheet" />は使用できません。

順序とマージ

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

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

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

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

  • CSSファイルは単一のJS/TSファイルでのみインポートする。
    • グローバルクラス名を使用する場合は、適用したい順序で同じファイル内にグローバルスタイルをインポートする。
  • グローバルスタイルよりもCSSモジュールを優先する。
    • CSSモジュールには一貫した命名規則を使用する。例えば、<name>.tsxよりも<name>.module.cssを使用する。
  • 共有スタイルは別の共有コンポーネントに抽出する。
  • Tailwindを使用する場合は、ファイルの先頭でスタイルシートをインポートし、できればルートレイアウトに配置する。
  • インポートを自動的に並べ替えるリンター/フォーマッター(例:ESLintのsort-import)はオフにする。これはCSSのインポート順序が_重要_であるため、意図せずCSSに影響を与える可能性があります。

補足:

  • CSS順序は開発モードでは異なる動作をする可能性があるため、最終的なCSS順序を確認するためにビルド(next build)を必ず確認してください。
  • next.config.jscssChunkingオプションを使用して、CSSのチャンク化を制御することができます。

追加機能

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

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