CSS のビルトインサポート

Next.js では、 JavaScript ファイルから CSS をインポートできます。 これは、 Next.js が JavaScript の import の概念を拡張することで実現しています。

グローバルスタイルシートの追加

スタイルシートをアプリケーションへ追加するために、 pages/_app.js 内で CSS ファイルをインポートしてみましょう。

例として、 styles.css という次のようなスタイルシートを考えます:

body {
  font-family: 'SF Pro Text', 'SF Pro Icons', 'Helvetica Neue', 'Helvetica', 'Arial', sans-serif;
  padding: 20px 20px 60px;
  max-width: 680px;
  margin: 0 auto;
}

もし、まだ作成していない場合は、 pages/_app.js を作成してください。 そして、 styles.cssimport してみましょう。

import '../styles.css';

// この default export は、新たに作成した `pages/_app.js` で必要になります。
export default function MyApp({ Component, pageProps }) {
  return <Component {...pageProps} />;
}

このスタイルシート (styles.css) は、アプリケーション内におけるすべての pages および components に適用されます。 スタイルシートのグローバルな性質のため、そして競合を回避するため、 pages/_app.js 内にのみインポートできます

開発環境では、スタイルシートをこのように表現することで、スタイルを編集している最中にホットリロードできます。 つまり、アプリケーションの状態を維持できるということです。

本番環境では、すべての CSS ファイルは、単一の minify された .css ファイルへと自動的に統合されます。

コンポーネントレベル CSS の追加

Next.js では、[name].module.css という命名規則に則ることで、 CSS Modules がサポートされます。

CSS Modules は、一意なクラス名を自動生成することで、 CSS をローカルなスコープにします。 これによって、クラス名の衝突を心配することなく、異なるファイルに同一の CSS クラス名を用いることができます。

こういった特徴のおかげで、CSS Modules はコンポーネントレベルの CSS を導入するための理想的な方法となっています。 CSS Module ファイルは、アプリケーション内のいかなる場所でもインポートできます

例として、 components/ フォルダ内の再利用可能な Button コンポーネントを考えます:

まず、次のような内容で components/Button.module.css ファイルを作成します:

/*
.error {} が他の `.css` や `.module.css` ファイルと衝突することを心配する必要はありません!
*/
.error {
  color: white;
  background-color: red;
}

そして、 上記の CSS ファイルをインポートして利用し、 components/Button.js を作成します:

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

export function Button() {
  return (
    <button
      type="button"
      // "error" クラスがインポートされた `styles` オブジェクトのプロパティとして
      // アクセスされることに注意してください。
      className={styles.error}
    >
      Destroy
    </button>
  );
}

CSS Modules は、 .module.css 拡張子ファイルに対してのみ有効となるオプション機能です。 なお、通常の <link> スタイルシートやグローバル CSS ファイルもサポートされています。

本番環境では、すべての CSS Module ファイルはコード分割した上で minify された複数の .css ファイルへと自動的に統合されます。 これらの .css ファイルは、アプリケーション内のホット実行パスを表しており、アプリケーションが描画のために読み込む CSS を最小限にすることを保証します。

Sassのサポート

Next.js では、 .scss または .sass のどちらの拡張子を用いた Sass ファイルでもインポートできます。 CSS Modules によるコンポーネントレベルの Sass を、 .module.scss または .module.sass の拡張子で利用できます。

Sass のビルトインサポートを利用する前に、必ず sass をインストールしてください:

npm install sass

Sass サポートには、前節で詳説した CSS ビルトインサポートと同様の恩恵と制限があります。

Sass 設定のカスタマイズ

もし、Sass コンパイラーの設定をしたい場合、next.config.js 内の sassOptions を利用できます。

例として、 includePaths を追加します:

const path = require('path');

module.exports = {
  sassOptions: {
    includePaths: [path.join(__dirname, 'styles')]
  }
};

Less や Stylus のサポート

.less.styl といったファイルのインポートには、次のプラグインを利用できます:

less プラグインを利用する場合、 必ず less の依存関係を追加することを忘れないでください。 さもなくば、次のようなエラーが起こります:

Error: Cannot find module 'less'

CSS-in-JS

利用できる CSS-in-JS の例

既存のいかなる CSS-in-JS も利用できます。 最も単純なのは、インラインスタイルを用いる方法です:

function HiThere() {
  return <p style={{ color: 'red' }}>hi there</p>;
}

export default HiThere;

分離された scoped CSS へのサポートを提供するために、 Next.js では styled-jsx を付属しています。 その目的は、残念ながら サーバーレンダリングをサポートしていない Web Components に似ている "shadow CSS" をサポートすることにあります。

その他の CSS-in-JS (Styled Components など ) については、上記の例をご覧ください。

styled-jsx を利用したコンポーネントは次のようになります:

function HelloWorld() {
  return (
    <div>
      Hello world
      <p>scoped!</p>
      <style jsx>{`
        p {
          color: blue;
        }
        div {
          background: red;
        }
        @media (max-width: 600px) {
          div {
            background: blue;
          }
        }
      `}</style>
      <style global jsx>{`
        body {
          background: black;
        }
      `}</style>
    </div>
  );
}

export default HelloWorld;

より多くの具体例については、 styled-jsx documentation をご覧ください。

関連事項

次にやるべきこととして、以下のセクションを読むことを推奨します: