Stylesheets

Next.js는 다양한 유형의 스타일시트를 지원합니다:

CSS Modules

Next.js는 .module.css 확장자를 사용하여 CSS Modules를 기본적으로 지원합니다.

CSS Modules는 자동으로 고유한 클래스 이름을 생성하여 CSS를 로컬 스코프로 지정합니다. 이를 통해 다른 파일에서 동일한 클래스 이름을 충돌 없이 사용할 수 있습니다. 이러한 동작은 CSS Modules를 컴포넌트 수준의 CSS를 포함시키는 이상적인 방법으로 만듭니다.

Example

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/layout.js
import styles from './styles.module.css'
 
export default function DashboardLayout({ children }) {
  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만 로드되도록 합니다.

Global Styles

글로벌 스타일은 app 디렉토리 내의 모든 레이아웃, 페이지 또는 컴포넌트에 임포트할 수 있습니다.

알아두면 좋은 점:

  • 이것은 pages 디렉토리와 다르며, pages 디렉토리에서는 글로벌 스타일을 _app.js 파일 내에서만 임포트할 수 있습니다.
  • Next.js는 실제로 글로벌인 스타일, 즉 모든 페이지에 적용될 수 있고 애플리케이션의 수명 동안 유지될 수 있는 스타일이 아니면 글로벌 스타일의 사용을 지원하지 않습니다. 이는 Next.js가 React의 내장 스타일 시트 지원을 사용하여 Suspense와 통합하기 때문입니다. 이 내장 지원은 현재 경로 간 탐색 시 스타일 시트를 제거하지 않습니다. 따라서 글로벌 스타일보다 CSS Modules를 사용하는 것이 좋습니다.

예를 들어, 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
// 이 스타일은 애플리케이션의 모든 경로에 적용됩니다.
import './global.css'
 
export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html lang="en">
      <body>{children}</body>
    </html>
  )
}
app/layout.js
// 이 스타일은 애플리케이션의 모든 경로에 적용됩니다.
import './global.css'
 
export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body>{children}</body>
    </html>
  )
}

External Stylesheets

외부 패키지에서 발행된 스타일 시트는 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>
  )
}
app/layout.js
import 'bootstrap/dist/css/bootstrap.css'
 
export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body className="container">{children}</body>
    </html>
  )
}

알아두면 좋은 점: 외부 스타일 시트는 npm 패키지에서 직접 임포트하거나 다운로드하여 코드베이스와 함께 위치해야 합니다. <link rel="stylesheet" />를 사용할 수 없습니다.

Ordering and Merging

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} />
}
base-button.js
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} />
}
page.js
import { BaseButton } from './base-button'
import styles from './page.module.css'
 
export function Page() {
  return <BaseButton className={styles.primary} />
}

예측 가능한 순서를 유지하려면 다음을 권장합니다:

  • 단일 JS/TS 파일에서만 CSS 파일을 임포트합니다.
    • 글로벌 클래스 이름을 사용하는 경우, 동일한 파일에서 임포트하여 적용하고자 하는 순서대로 글로벌 스타일을 임포트합니다.
  • 글로벌 스타일보다 CSS Modules를 선호합니다.
    • CSS 모듈에 일관된 명명 규칙을 사용합니다. 예를 들어, <name>.module.css<name>.tsx보다 선호합니다.
  • 공유 스타일을 별도의 공유 컴포넌트로 추출합니다.
  • Tailwind를 사용하는 경우, 파일 상단에 스타일 시트를 임포트합니다. 가능한 Root Layout에서 임포트합니다.
  • 임포트를 자동으로 정렬하는 린터/포매터(예: ESLint의 sort-import (opens in a new tab))를 비활성화합니다. 이는 CSS 임포트 순서가 중요하기 때문에 의도치 않게 CSS에 영향을 줄 수 있습니다.

알아두면 좋은 점:

  • 개발 모드에서 CSS 순서는 다르게 작동할 수 있으므로, 최종 CSS 순서를 확인하려면 빌드(next build)를 확인하세요.
  • next.config.js에서 cssChunking 옵션을 사용하여 CSS 청킹 방식을 제어할 수 있습니다.

Additional Features

Next.js는 스타일 추가 경험을 개선하기 위해 추가 기능을 포함합니다:

  • 로컬에서 next dev를 실행할 때, 로컬 스타일 시트(글로벌 또는 CSS 모듈)는 Fast Refresh를 활용하여 편집이 저장될 때 즉시 변경 사항을 반영합니다.
  • next build를 사용하여 프로덕션을 빌드할 때, CSS 파일은 더 적은 수의 미니파이된 .css 파일로 번들링되어 스타일을 검색하는 데 필요한 네트워크 요청 수를 줄입니다.
  • JavaScript를 비활성화하면, 프로덕션 빌드(next start)에서는 스타일이 여전히 로드됩니다. 그러나 next dev에서는 Fast Refresh를 활성화하기 위해 여전히 JavaScript가 필요합니다.