🚀

【Next.js和訳】Basic Features/Built-in CSS Support

8 min read

この記事について

株式会社 UnReact はプロジェクトの一環としてNext.js ドキュメントの和訳を行っています。

この記事は、Basic Features/Built-in CSS Supportの記事を和訳したものです。

記事内で使用する画像は、公式ドキュメント内の画像を引用して使用させていただいております。


ビルトインCSSサポート

Next.jsでは、JavaScriptファイルからCSSファイルをインポートすることができます。これは、Next.jsがimportの概念をJavaScriptよりも拡張しているために可能となっています。

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

アプリケーションにスタイルシートを追加するには、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 fileがなければ作成します. そして styles.cssファイルをimportします。

import '../styles.css'
// このデフォルトのエクスポートは、新しい `pages/_app.js` ファイルで必要です。
export default function MyApp({ Component, pageProps }) {
  return <Component {...pageProps} />
}

これらのスタイル(styles.css)は、アプリケーション内のすべてのページとコンポーネントに適用されます。スタイルシートはグローバルな性質を持っているため、競合を避けるために、pages/_app.js内でのみインポートすることができます

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

本番環境では、すべてのCSSファイルは自動的に1つの最小化された.cssファイルに結合されます。

node_modulesからのスタイルの読み込み

Next.js 9.5.4以降では、node_modulesからCSSファイルをインポートすることが、アプリケーションのどこでも可能になりました。

bootstrapnprogressのようなグローバルスタイルシートの場合は、pages/_app.js内でインポートする必要があります。例えば、以下のようになります。

pages/_app.js
import 'bootstrap/dist/css/bootstrap.css'
export default function MyApp({ Component, pageProps }) {
  return <Component {...pageProps} />
}

サードパーティ製のコンポーネントで必要なCSSをインポートする場合は、自分のコンポーネントで行うことができます。例えば、以下のようになります。

components/ExampleDialog.js
import { useState } from 'react'
import { Dialog } from '@reach/dialog'
import VisuallyHidden from '@reach/visually-hidden'
import '@reach/dialog/styles.css'
function ExampleDialog(props) {
  const [showDialog, setShowDialog] = useState(false)
  const open = () => setShowDialog(true)
  const close = () => setShowDialog(false)
  return (
    <div>
      <button onClick={open}>Open Dialog</button>
      <Dialog isOpen={showDialog} onDismiss={close}>
        <button className="close-button" onClick={close}>
          <VisuallyHidden>Close</VisuallyHidden>
          <span aria-hidden>×</span>
        </button>
        <p>Hello there. I am a dialog</p>
      </Dialog>
    </div>
  )
}

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

Next.jsは、[name].module.cssというファイル命名規則を用いたCSSモジュールをサポートしています。

CSSモジュールは、ユニークなクラス名を自動的に作成することで、CSSをローカルにスコープします。これにより、衝突を気にすることなく、同じCSSクラス名を異なるファイルで使用することができます。

この動作により、CSS モジュールはコンポーネントレベルの CSS を含めるための理想的な方法となっています。CSS モジュールのファイルは、アプリケーションのどこにでもインポートすることができます

例えば、components/フォルダにある再利用可能なButtonコンポーネントを考えてみましょう。

まず、components/Button.module.cssを次のような内容で作成します。

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

次に、components/Button.jsを作成し、上記のCSSファイルをインポートして使用します。

import styles from './Button.module.css'
export function Button() {
  return (
    <button
      type="button"
      // インポートされた「error」クラスがどのようにプロパティとしてアクセスされるかに注目してください。
      // `styles` object.
      className={styles.error}
    >
      Destroy
    </button>
  )
}

CSS モジュールはオプションの機能で、拡張子が .module.css のファイルに対してのみ有効です。通常の <link> スタイルシートやグローバル CSS ファイルは引き続きサポートされています。

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

Sassのサポート

Next.jsでは、.scss.sassの両方の拡張子を使ってSassをインポートすることができます。コンポーネントレベルのSassは、CSSモジュールと.module.scssまたは.module.sass拡張子を使って使用できます。

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

npm install sass

Sassのサポートは、上記のビルトインCSSサポートと同じ利点と制限があります。

Note
Sassは2つの異なる構文をサポートしており、それぞれ独自の拡張子を持っています。.scssの拡張子ではSCSSの構文を使用する必要があり、.sassの拡張子ではIndented Syntax(「Sass」)を使用する必要があります。

どちらを選べばよいかわからない場合は、CSSのスーパーセットである.scss拡張子から始めて、Indented Syntax(「Sass」)を学ぶ必要はありません。

Sassオプションのカスタマイズ

Sassコンパイラーを設定したい場合は、next.config.jssassOptionsを使用することができます。

例えば、includePathsを追加するには、次のようにします。

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

CSS-in-JS

既存のCSS-in-JSソリューションを利用することが可能です。最もシンプルなものはインラインスタイルです。

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

私たちは styled-jsx をバンドルして、分離されたスコープ付きの CSS のサポートを提供しています。目的は Web Components に似た「影の CSS」をサポートすることですが、残念ながらサーバーレンダリングはサポートされておらず、JS のみのサポートとなります。

他の一般的な 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 のドキュメントをご覧ください。

よくある質問

JavaScriptを無効にしても動作しますか?

はい、JavaScriptを無効にしても、プロダクションビルド(next start)にはCSSが読み込まれます。開発中は、Fast Refreshで最高の開発環境を提供するために、JavaScriptを有効にする必要があります。

関連情報

次に行うべきことの詳細については、以下のセクションをお勧めします。

https://nextjs.org/docs/advanced-features/customizing-postcss-config

Discussion

ログインするとコメントできます