メインコンテンツまでスキップ

CSS

Next.jsはCSSを処理するための複数の方法をサポートしています:

CSS Modules

Next.jsには、.module.css拡張子を使用したCSS Modulesのサポートが組み込まれています。

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

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

app/dashboard/layout.tsx
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 Modulesは、.module.cssおよび.module.sass拡張子を持つファイルに対してのみ有効です

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

グローバルスタイル

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

知っておくとよいこと:

  • これはpagesディレクトリとは異なります。pagesディレクトリでは、グローバルスタイルを_app.jsファイルの中でのみインポートできます。
  • Next.jsはグローバルでないスタイルの使用をサポートしません。つまり、すべてのページに適用でき、アプリケーションのライフタイム全体で存続できるものである必要があります。これは、Next.jsがスタイルシートをSuspenseと統合するためにReactの組み込みサポートを使用しているためです。この組み込みサポートは現在、ルート間を移動する際にスタイルシートを削除しません。この理由から、グローバルスタイルよりもCSS Modulesを使用することをお勧めします。

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

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

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

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

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

外部スタイルシート

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

app/layout.tsx
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
import styles from './base-button.module.css'

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

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

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

  • CSSファイルを単一のJS/TSファイルでのみインポートする
    • グローバルクラス名を使用する場合、適用したい順序で同じファイル内にグローバルスタイルをインポートする
  • グローバルスタイルよりもCSS Modulesを好む
    • CSSモジュールに一貫した命名規約を使用する。例えば、<name>.module.css<name>.tsxにする
  • 共有スタイルを別の共有コンポーネントに抽出する
  • Tailwindを使用している場合、できればRoot Layoutで、ファイルの先頭でスタイルシートをインポートする
  • 自動的にインポートをソートするリンター/フォーマッター(例:ESLintのsort-import)をオフにする。このソートは、CSSのインポート順序にinadvertently影響を与える可能性があります

知っておくとよいこと:

  • 開発モードでは、CSSの順序が異なる動作をする場合がありますので、ビルド(next build)をチェックして最終的なCSS順序を確認してください。
  • cssChunkingオプションをnext.config.jsで使用して、CSSがどのようにチャンクされるかを制御できます。

追加機能

Next.jsには、スタイルを追加する際のオーサリング体験を向上させるための追加機能があります:

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