icon
9장 : 스타일링과 CSS

Tailwind CSS 설정 및 사용

이전 절에서 CSS 모듈, Sass, 그리고 CSS-in-JS와 같은 다양한 스타일링 접근 방식을 살펴보았습니다. 각 방식은 고유한 장단점을 가지고 있으며, 프로젝트의 요구사항에 따라 선택됩니다. 이번 절에서는 최근 몇 년간 프론트엔드 개발 커뮤니티에서 폭발적인 인기를 얻고 있는 Tailwind CSS에 대해 알아보겠습니다.

Tailwind CSS는 유틸리티 우선(Utility-first) CSS 프레임워크로, 미리 정의된 작은 유틸리티 클래스들을 HTML 마크업에 직접 적용하여 스타일을 구성하는 방식입니다. 이는 기존 CSS 작성 방식과는 다른 새로운 패러다임을 제시하며, 빠른 개발 속도와 일관된 디자인 시스템 구축에 큰 강점을 보입니다. Next.js는 Tailwind CSS와의 통합을 매우 쉽고 효율적으로 지원합니다.


Tailwind CSS란 무엇인가요?

Tailwind CSS는 저수준(low-level) CSS 프레임워크입니다. btn, card와 같은 의미론적인(semantic) 클래스 이름을 미리 정의하여 제공하는 대신, flex, pt-4, text-center, rotate-90 등과 같이 CSS 속성-값 쌍에 직접 매핑되는 수많은 유틸리티 클래스를 제공합니다.

핵심 특징

  • 유틸리티 우선(Utility-first): HTML 요소에 class 속성으로 여러 개의 유틸리티 클래스를 조합하여 스타일을 만듭니다.
  • 컴파일 시점에 CSS 생성: 개발자가 사용한 유틸리티 클래스만 최종 CSS 번들에 포함되므로, 매우 작은 CSS 파일을 생성할 수 있습니다 (PurgeCSS 또는 JIT Engine 활용).
  • 높은 커스터마이징 가능성: tailwind.config.js 파일을 통해 디자인 토큰(색상, 폰트, 간격 등)을 자유롭게 확장하고 변경할 수 있습니다.
  • 반응형 디자인 내장: sm:, md:, lg: 등과 같은 접두사를 사용하여 반응형 디자인을 쉽게 구현할 수 있습니다.
  • 의사 클래스(Pseudo-classes) 지원: hover:, focus:, active: 등과 같은 접두사를 사용하여 상호작용 상태의 스타일을 직접 적용할 수 있습니다.

예시

<button class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
  버튼
</button>

위 코드는 background-color, padding, font-weight, border-radius 등 여러 CSS 속성들을 유틸리티 클래스로 조합하여 하나의 버튼을 스타일링합니다.


왜 Tailwind CSS를 사용해야 할까요? (이점)

Tailwind CSS는 다음과 같은 강력한 이점들을 제공합니다.

  • 빠른 개발 속도: CSS 파일을 오가며 클래스 이름을 고민하거나 새로 작성할 필요 없이, HTML 마크업 내에서 빠르게 스타일을 적용할 수 있습니다.
  • 일관된 디자인 시스템: 미리 정의된 유틸리티 클래스들은 팀 내에서 일관된 간격, 색상, 타이포그래피 등을 사용하도록 강제하여, 디자인 가이드를 준수하기 쉽게 만듭니다.
  • 유지보수성 향상: 컴포넌트를 복사하여 붙여넣으면 스타일까지 함께 복사되므로, CSS 모듈과 유사하게 스타일 고립의 이점을 얻을 수 있습니다. 특정 컴포넌트의 스타일 변경이 다른 컴포넌트에 영향을 줄 위험이 적습니다.
  • 작은 최종 CSS 번들 크기: 필요한 유틸리티 클래스만 최종 빌드에 포함되므로, 프로덕션 환경에서 매우 최적화된 CSS 파일을 얻을 수 있습니다.
  • 런타임 오버헤드 없음: CSS-in-JS와 달리 JavaScript 런타임에서 스타일을 생성하지 않으므로, 런타임 성능 저하가 없습니다.
  • 쉬운 반응형 디자인: 직관적인 접두사를 통해 모바일 우선(mobile-first) 또는 데스크톱 우선 반응형 디자인을 쉽게 구현할 수 있습니다.

Next.js에서 Tailwind CSS 설정 및 사용하기

Next.js는 Tailwind CSS를 위한 공식적인 설치 가이드를 제공하며, 설정 과정이 매우 간단합니다.

  1. Next.js 프로젝트 생성 (또는 기존 프로젝트 사용): 만약 새로운 프로젝트를 시작한다면, npx create-next-app@latest 명령어를 통해 프로젝트를 생성할 때 Tailwind CSS를 포함할 것인지 묻는 질문에 'Yes'라고 답하면 됩니다.

    npx create-next-app@latest my-app-with-tailwind
    # ? Would you like to use Tailwind CSS? Yes

    기존 프로젝트에 추가하는 경우 다음 단계를 따릅니다.

  2. 필요한 패키지 설치: tailwindcss, postcss, autoprefixer를 개발 의존성으로 설치합니다.

    npm install -D tailwindcss postcss autoprefixer
    # 또는
    yarn add -D tailwindcss postcss autoprefixer
  3. Tailwind CSS 설정 파일 생성: 다음 명령어를 실행하여 Tailwind CSS 설정 파일을 초기화합니다.

    npx tailwindcss init -p

    이 명령어는 프로젝트 루트에 두 개의 파일을 생성합니다:

    • tailwind.config.js: Tailwind CSS의 기본 설정을 커스터마이징할 수 있는 파일.
    • postcss.config.js: PostCSS 플러그인을 설정하는 파일 (Tailwind CSS와 Autoprefixer가 포함됨).
  4. tailwind.config.js 설정: tailwind.config.js 파일을 열어 content 배열에 Tailwind CSS를 사용할 파일 경로를 추가합니다. 이는 Tailwind CSS가 어떤 파일들에서 유틸리티 클래스를 스캔하여 최종 CSS를 생성할지 알려주는 역할을 합니다.

    tailwind.config.js
    // tailwind.config.js
    /** @type {import('tailwindcss').Config} */
    module.exports = {
      content: [
        './app/**/*.{js,ts,jsx,tsx,mdx}', // src/app 디렉토리 내의 모든 파일
        './pages/**/*.{js,ts,jsx,tsx,mdx}', // pages 디렉토리 내의 모든 파일 (기존)
        './components/**/*.{js,ts,jsx,tsx,mdx}', // components 디렉토리 내의 모든 파일
      ],
      theme: {
        extend: {},
      },
      plugins: [],
    };
  5. 전역 CSS 파일에 Tailwind 지시어 추가: Next.js의 전역 CSS 파일 (src/app/globals.css 또는 src/styles/globals.css 등)에 Tailwind CSS의 기본 지시어들을 추가합니다.

    src/app/globals.css
    /* src/app/globals.css */
    @tailwind base;
    @tailwind components;
    @tailwind utilities;
    
    /* 여기에 커스텀 전역 스타일을 추가할 수 있습니다. */
    body {
      font-family: Arial, sans-serif;
    }

    이 지시어들은 Tailwind CSS가 생성하는 base (기본 스타일), components (컴포넌트 클래스), utilities (유틸리티 클래스)를 해당 위치에 주입하도록 합니다.

  6. 전역 CSS 파일을 Root Layout에 임포트: src/app/layout.tsx 파일에 위에서 설정한 전역 CSS 파일을 임포트합니다.

    src/app/layout.tsx
    // src/app/layout.tsx
    import './globals.css'; // Tailwind CSS 지시어가 포함된 전역 CSS 파일 임포트
    
    export default function RootLayout({
      children,
    }: {
      children: React.ReactNode;
    }) {
      return (
        <html lang="ko">
          <body>{children}</body>
        </html>
      );
    }

이제 Tailwind CSS를 사용할 준비가 완료되었습니다!


Tailwind CSS 사용 예시

이제 컴포넌트나 페이지의 JSX/TSX 파일에서 Tailwind CSS 유틸리티 클래스를 직접 사용할 수 있습니다.

실습: Tailwind CSS로 버튼과 카드 컴포넌트 스타일링

src/app/tailwind-css/page.tsx
// src/app/tailwind-css/page.tsx (서버 컴포넌트)

// 클라이언트 컴포넌트를 사용하기 위해 use client 지시어를 가진 파일 임포트
import TailwindButton from './TailwindButton';
import TailwindCard from './TailwindCard';

export default function TailwindCssPage() {
  return (
    <div className="flex flex-col items-center justify-center min-h-screen bg-gray-100 p-8">
      <h1 className="text-4xl font-bold text-gray-800 mb-8">
        Tailwind CSS 예제
      </h1>
      <p className="text-lg text-gray-600 mb-12 text-center">
        유틸리티 클래스를 사용하여 컴포넌트를 빠르게 스타일링합니다.
      </p>

      <div className="flex flex-col md:flex-row gap-8 w-full max-w-4xl">
        {/* TailwindButton은 클라이언트 컴포넌트 */}
        <TailwindButton />

        {/* TailwindCard는 클라이언트 컴포넌트 */}
        <TailwindCard title="Tailwind 카드" description="이것은 Tailwind CSS로 스타일링된 카드 컴포넌트입니다.">
          <p className="text-gray-700">추가적인 내용입니다.</p>
          <button className="mt-4 px-4 py-2 bg-purple-600 text-white rounded-lg hover:bg-purple-700 transition-colors">
            자세히 보기
          </button>
        </TailwindCard>
      </div>
    </div>
  );
}
src/app/tailwind-css/TailwindButton.tsx
// src/app/tailwind-css/TailwindButton.tsx (클라이언트 컴포넌트)
"use client";

import React, { useState } from 'react';

export default function TailwindButton() {
  const [count, setCount] = useState(0);

  return (
    <div className="flex flex-col items-center p-6 bg-white rounded-xl shadow-lg w-full md:w-1/2">
      <h2 className="text-2xl font-semibold text-gray-700 mb-4">카운터 버튼</h2>
      <p className="text-xl text-blue-600 mb-4">현재 카운트: <span className="font-bold">{count}</span></p>
      <button
        onClick={() => setCount(prev => prev + 1)}
        className="bg-blue-500 hover:bg-blue-600 text-white font-bold py-3 px-6 rounded-lg shadow-md transition-all duration-300 ease-in-out transform hover:scale-105 active:scale-95"
      >
        클릭하여 카운트 증가
      </button>
      <p className="mt-4 text-sm text-gray-500">이 버튼은 클라이언트 컴포넌트에서 상태를 관리합니다.</p>
    </div>
  );
}
src/app/tailwind-css/TailwindCard.tsx
// src/app/tailwind-css/TailwindCard.tsx (클라이언트 컴포넌트)
"use client";

import React from 'react';

interface TailwindCardProps {
  title: string;
  description: string;
  children?: React.ReactNode;
}

export default function TailwindCard({ title, description, children }: TailwindCardProps) {
  return (
    <div className="bg-white p-8 rounded-xl shadow-lg hover:shadow-xl transition-shadow duration-300 w-full md:w-1/2">
      <h2 className="text-3xl font-bold text-gray-800 mb-4">
        {title}
      </h2>
      <p className="text-gray-600 mb-6 leading-relaxed">
        {description}
      </p>
      {children}
    </div>
  );
}

실습 확인

  1. 위에서 설명한 Tailwind CSS 설치 및 설정 (tailwind.config.js, globals.css)을 완료합니다.
  2. src/app/tailwind-css 폴더를 만들고 위 page.tsx, TailwindButton.tsx, TailwindCard.tsx 파일을 생성합니다.
  3. 개발 서버(npm run dev)를 실행한 후, http://localhost:3000/tailwind-css로 접속합니다.
  • Tailwind CSS 클래스들이 적용된 깔끔한 UI를 확인할 수 있습니다.
  • "클릭하여 카운트 증가" 버튼을 눌러 상태 변화와 스타일이 잘 작동하는지 확인합니다.
  • 브라우저 개발자 도구를 열어 요소들의 클래스 목록을 확인하면, CSS-in-JS나 CSS 모듈처럼 해시값이 붙지 않고 작성된 유틸리티 클래스 이름 그대로 나타나는 것을 볼 수 있습니다.

Tailwind CSS의 장점과 고려사항

장점

  • 극강의 개발 생산성: CSS 파일을 오가지 않고 HTML/JSX 내에서 거의 모든 스타일을 구현할 수 있습니다.
  • 최적화된 CSS 번들: 사용하지 않는 CSS는 포함되지 않아 최종 빌드 파일이 매우 작습니다.
  • 일관된 디자인: 디자인 토큰을 기반으로 하므로 일관된 디자인 시스템을 자연스럽게 강제합니다.
  • 유지보수 용이: 컴포넌트의 스타일이 컴포넌트 자체에 캡슐화되어 있어, 다른 컴포넌트와의 충돌 위험이 적습니다.

고려사항

  • 긴 클래스 목록: 복잡한 컴포넌트의 경우 class 속성이 매우 길어질 수 있습니다. @apply 지시어를 사용하여 반복되는 유틸리티 클래스 묶음을 커스텀 클래스로 추상화할 수 있지만, 이는 Tailwind의 핵심 철학에서 벗어날 수 있습니다.
  • 초기 학습 곡선: 기존 CSS에 익숙한 개발자는 유틸리티 우선 방식에 적응하는 데 시간이 걸릴 수 있습니다. 모든 스타일이 클래스 이름으로 어떻게 매핑되는지 학습해야 합니다.
  • 정적 웹사이트에 강점: 동적인 스타일(런타임에 완전히 새로운 스타일 생성)에는 CSS-in-JS가 더 유리할 수 있습니다. 하지만 Tailwind도 변수나 동적 클래스 바인딩을 통해 어느 정도 동적 스타일을 처리할 수 있습니다.
  • 직접 CSS 작성의 감소: 때로는 직접 CSS를 작성해야 할 필요성을 느끼지 못하게 되어, CSS의 기본 개념에 대한 이해도가 낮아질 수 있다는 비판도 있습니다.

Tailwind CSS는 빠른 개발, 일관된 디자인 시스템, 그리고 최적화된 성능을 중시하는 프로젝트에 매우 훌륭한 선택입니다. 특히 Next.js와 함께 사용하면 설치 및 설정이 간편하여 즉시 생산성을 높일 수 있습니다. 프로젝트의 특성과 팀의 선호도에 맞춰 Tailwind CSS를 고려해 보세요.