CSS Styling

현재 홈 페이지에는 스타일이 없습니다. Next.js 애플리케이션의 스타일을 지정할 수 있는 다양한 방법을 살펴보겠습니다.

이 장에서

우리가 다룰 주제는 다음과 같습니다

  • 애플리케이션에 전역 CSS 파일을 추가하는 방법.
  • 두 가지 스타일 지정 방법: Tailwind 및 CSS 모듈.
  • clsx 유틸리티 패키지를 사용하여 조건부로 클래스 이름을 추가하는 방법.
Tailwind CSS

Tailwind CSS는 유틸리티 퍼스트(Utility-First) 접근 방식을 사용하는 CSS 프레임워크입니다. HTML 클래스에 미리 정의된 CSS 유틸리티 클래스를 추가하여 스타일을 빠르게 적용할 수 있으며 다음의 장점이 있습니다.

  • 빠른 개발: CSS 작성 없이 바로 스타일을 적용 가능.
  • 유지보수 용이: 클래스 기반으로 스타일을 명확하게 관리.
  • 디자인 일관성: 프레임워크가 제공하는 제한된 옵션 내에서 스타일 지정.

글로벌 스타일

/app/ui 폴더를 살펴보면 global.css라는 파일이 있습니다. 이 파일을 사용하여 CSS 재설정 규칙, 링크와 같은 HTML 요소에 대한 사이트 전체 스타일 등과 같은 CSS 규칙을 애플리케이션의 모든 경로에 추가할 수 있습니다.

애플리케이션의 모든 구성 요소에서 global.css를 가져올 수 있지만 일반적으로 최상위 구성 요소에 추가하는 것이 좋습니다. Next.js에서 이는 루트 레이아웃입니다. (나중에 자세히 설명).

/app/layout.tsx로 이동하고 global.css 파일을 가져와 애플리케이션에 전역 스타일을 추가합니다.

import '@/app/ui/global.css';

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

코드설명

code 설명
import
  • CSS 파일을 JavaScript/TypeScript 파일에 가져오는 역할을 합니다.

  • Webpack, Vite, 또는 Next.js와 같은 번들러가 CSS 파일을 처리하도록 알려줍니다.

‘@/app/ui/global.css’
  • CSS 파일의 경로를 나타냅니다.

  • @/프로젝트 루트 경로를 나타내는 **Alias(별칭)**입니다.

  • Next.js에서는 기본적으로 @가 프로젝트의 루트 디렉터리를 가리키도록 설정되어 있습니다.

    프로젝트 루트
    └── app
        └── ui
            └── global.css
global.css
  • 전역 스타일 정의를 포함한 CSS 파일.

개발 서버가 계속 실행 중인 상태에서 변경 사항을 저장하고 브라우저에서 미리 봅니다. 이제 홈 페이지는 다음과 같아야 합니다.

그런데 잠깐만요. CSS 규칙을 추가하지 않았는데, 스타일은 어디서 나온 걸까요? global.css 내부를 살펴보면 @tailwind 지시문을 볼 수 있습니다.

@tailwind base;
@tailwind components;
@tailwind utilities;

Tailwind

Tailwind는 React 코드에서 직접 유틸리티 클래스를 빠르게 작성할 수 있도록 하여 개발 프로세스 속도를 높이는 CSS 프레임워크입니다.

Tailwind에서는 클래스 이름을 추가하여 요소의 스타일을 지정합니다. 예를 들어 “text-blue-500”을 추가하면 <h1> 텍스트가 파란색으로 변합니다.

<h1 className="text-blue-500">I'm blue!</h1>

CSS 스타일은 전역적으로 공유되지만 각 클래스는 각 요소에 개별적으로 적용됩니다. 즉, 요소를 추가하거나 삭제하는 경우 별도의 스타일시트 유지 관리, 스타일 충돌 또는 애플리케이션 확장에 따른 CSS 번들 크기 증가에 대해 걱정할 필요가 없습니다.

create-next-app을 사용하여 새 프로젝트를 시작하면 Next.js가 Tailwind를 사용할지 묻습니다. yes를 선택하면 Next.js가 자동으로 필요한 패키지를 설치하고 애플리케이션에 Tailwind를 구성합니다.

/app/page.tsx를 보면 예제에서 Tailwind 클래스를 사용하고 있음을 알 수 있습니다.

import AcmeLogo from '@/app/ui/acme-logo';
import { ArrowRightIcon } from '@heroicons/react/24/outline';
import Link from 'next/link';

export default function Page() {
  return (
    // These are Tailwind classes:
    <main className="flex min-h-screen flex-col p-6">
      <div className="flex h-20 shrink-0 items-end rounded-lg bg-blue-500 p-4 md:h-52">
    // ...
  )
}

Tailwind를 처음 사용하는 경우에도 걱정하지 마세요. 시간을 절약하기 위해 사용할 모든 구성 요소에 이미 스타일을 지정했습니다.

Tailwind와 함께 놀자! 아래 코드를 복사하여 /app/page.tsx<p> 요소 위에 붙여넣습니다.

<div
  className="relative w-0 h-0 border-l-[15px] border-r-[15px] border-b-[26px] border-l-transparent border-r-transparent border-b-black"
/>

퀴즈를 풀 시간입니다!

지식을 테스트하고 방금 배운 내용을 확인하세요. 위의 코드 조각을 사용하면 어떤 모양이 보입니까?


전통적인 CSS 규칙을 작성하거나 스타일을 JSX와 별도로 유지하는 것을 선호한다면 CSS 모듈이 훌륭한 대안입니다.

CSS Modules

CSS 모듈을 사용하면 고유한 클래스 이름을 자동으로 생성하여 CSS 범위를 구성 요소로 지정할 수 있으므로 스타일 충돌에 대해서도 걱정할 필요가 없습니다.이 과정에서는 Tailwind를 계속 사용하지만 CSS 모듈을 사용하여 위 퀴즈에서 동일한 결과를 얻을 수 있는 방법을 잠시 살펴보겠습니다.

/app/ui 내에서 home.module.css라는 새 파일을 만들고 다음 CSS 규칙을 추가합니다.

.shape {
  height: 0;
  width: 0;
  border-bottom: 30px solid black;
  border-left: 20px solid transparent;
  border-right: 20px solid transparent;
}
그런 다음 /app/page.tsx 파일 내에서 스타일을 가져오고 추가한

의 Tailwind 클래스 이름을 styles.shape로 바꿉니다.

import AcmeLogo from '@/app/ui/acme-logo';
import { ArrowRightIcon } from '@heroicons/react/24/outline';
import Link from 'next/link';
import styles from '@/app/ui/home.module.css';

export default function Page() {
  return (
    <main className="flex min-h-screen flex-col p-6">
      <div className={styles.shape} />
    // ...
  )
}

변경 사항을 저장하고 브라우저에서 미리 봅니다. 이전과 같은 모양이 표시되어야 합니다.

Tailwind 및 CSS 모듈은 Next.js 애플리케이션 스타일을 지정하는 가장 일반적인 두 가지 방법입니다. 둘 중 하나를 사용하는지 여부는 선호의 문제입니다. 동일한 애플리케이션에서 두 가지를 모두 사용할 수도 있습니다!

퀴즈를 풀 시간입니다!

지식을 테스트하고 방금 배운 내용을 확인하세요. CSS 모듈을 사용하면 어떤 이점이 있나요?

Using the clsx library to toggle class names

상태나 다른 조건에 따라 요소의 스타일을 조건부로 지정해야 하는 경우가 있을 수 있습니다. clsx는 클래스 이름을 쉽게 전환할 수 있는 라이브러리입니다. 자세한 내용은 설명서를 살펴보는 것이 좋지만 기본 사용법은 다음과 같습니다.

상태를 허용하는 InvoiceStatus 구성 요소를 생성한다고 가정해 보겠습니다. 상태는 ‘대기 중’ 또는 ’지불됨’일 수 있습니다. ’유료’인 경우 색상이 녹색이기를 원합니다. ’보류 중’인 경우 색상이 회색이기를 원합니다. clsx를 사용하여 다음과 같이 클래스를 조건부로 적용할 수 있습니다.

/app/ui/invoices/status.tsx
import clsx from 'clsx';

export default function InvoiceStatus({ status }: { status: string }) {
  return (
    <span
      className={clsx(
        'inline-flex items-center rounded-full px-2 py-1 text-sm',
        {
          'bg-gray-100 text-gray-500': status === 'pending',
          'bg-green-500 text-white': status === 'paid',
        },
      )}
    >
    // ...
)}

Using the clsx library to toggle class names

상태 또는 다른 조건에 따라 조건부로 요소의 스타일을 지정해야 하는 경우가 있을 수 있습니다.

clsx는 클래스 이름을 쉽게 전환할 수 있는 라이브러리입니다. 자세한 내용은 설명서를 살펴보는 것이 좋지만 기본 사용법은 다음과 같습니다.

상태를 수락하는 InvoiceStatus 구성 요소를 만들려고 한다고 가정합니다. 상태는 ‘보류 중’ 또는 ’결제됨’일 수 있습니다. ’유료’인 경우 색상이 녹색이되기를 원합니다. ’보류 중’인 경우 색상을 회색으로 원합니다. 다음과 같이 clsx를 사용하여 클래스를 조건부로 적용할 수 있습니다.

/app/ui/invoices/status.tsx
import clsx from 'clsx';

export default function InvoiceStatus({ status }: { status: string }) {
  return (
    <span
      className={clsx(
        'inline-flex items-center rounded-full px-2 py-1 text-sm',
        {
          'bg-gray-100 text-gray-500': status === 'pending',
          'bg-green-500 text-white': status === 'paid',
        },
      )}
    >
    // ...
)}

Other styling solutions

우리가 논의한 접근 방식 외에도 다음을 사용하여 Next.js 응용 프로그램의 스타일을 지정할 수도 있습니다.

Sass를 사용하면 .css.scss 파일을 가져올 수 있습니다. styled-jsx, styled-componentsemotion과 같은 CSS-in-JS 라이브러리. 자세한 내용은 CSS 문서를 참조하십시오.