Как использовать CSS в вашем приложении

Next.js предоставляет несколько способов использования CSS в вашем приложении, включая:

CSS Modules

CSS Modules локально ограничивают область видимости CSS, генерируя уникальные имена классов. Это позволяет использовать один и тот же класс в разных файлах без риска конфликтов имен.

Чтобы начать использовать CSS Modules, создайте новый файл с расширением .module.css и импортируйте его в любой компонент внутри директории pages:

/styles/blog.module.css
.blog {
  padding: 24px;
}
import styles from './blog.module.css'

export default function Page() {
  return <main className={styles.blog}></main>
}
import styles from './blog.module.css'

export default function Page() {
  return <main className={styles.blog}></main>
}

Global CSS

Вы можете использовать глобальные стили для применения CSS-правил ко всему приложению.

Импортируйте таблицу стилей в файл pages/_app.js, чтобы применить стили ко всем маршрутам вашего приложения:

pages/_app.js
import '@/styles/global.css'

export default function MyApp({ Component, pageProps }) {
  return <Component {...pageProps} />
}

Из-за глобальной природы таблиц стилей и во избежание конфликтов их следует импортировать внутри pages/_app.js.

Внешние таблицы стилей

Next.js позволяет импортировать CSS-файлы из JavaScript-файла. Это возможно благодаря тому, что Next.js расширяет концепцию import за пределы JavaScript.

Импорт стилей из node_modules

Начиная с Next.js 9.5.4, импорт CSS-файлов из node_modules разрешен в любом месте вашего приложения.

Для глобальных таблиц стилей, таких как bootstrap или nprogress, файл следует импортировать в pages/_app.js. Например:

pages/_app.js
import 'bootstrap/dist/css/bootstrap.css'

export default function MyApp({ Component, pageProps }) {
  return <Component {...pageProps} />
}

Для импорта CSS, требуемого сторонним компонентом, это можно сделать непосредственно в компоненте. Например:

components/example-dialog.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>
  )
}

Порядок и объединение стилей

Next.js оптимизирует CSS во время production-сборки, автоматически объединяя (чанкуя) таблицы стилей. Порядок вашего CSS зависит от порядка импорта стилей в вашем коде.

Например, base-button.module.css будет расположен перед page.module.css, так как <BaseButton> импортируется до page.module.css:

import { BaseButton } from './base-button'
import styles from './page.module.css'

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

export default function Page() {
  return <BaseButton className={styles.primary} />
}
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} />
}

Рекомендации

Для предсказуемого порядка CSS:

  • Старайтесь ограничивать импорт CSS одним JavaScript или TypeScript entry-файлом
  • Импортируйте глобальные стили и Tailwind-стили в корне приложения
  • Используйте CSS Modules вместо глобальных стилей для вложенных компонентов
  • Используйте единое соглашение по именованию для CSS-модулей, например <name>.module.css вместо <name>.tsx
  • Выносите общие стили в общие компоненты, чтобы избежать дублирования импортов
  • Отключайте линтеры или форматтеры, автоматически сортирующие импорты, такие как ESLint sort-imports
  • Вы можете использовать опцию cssChunking в next.config.js для управления объединением CSS

Разработка vs Продакшен

  • В режиме разработки (next dev) обновления CSS применяются мгновенно благодаря Fast Refresh
  • В продакшене (next build) все CSS-файлы автоматически объединяются в минифицированные и чанкованные .css файлы, обеспечивая загрузку минимального количества CSS для маршрута
  • В продакшене CSS загружается даже при отключенном JavaScript, но в разработке JavaScript необходим для Fast Refresh
  • Порядок CSS может отличаться в разработке, всегда проверяйте сборку (next build), чтобы убедиться в окончательном порядке CSS