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를 위한 공식적인 설치 가이드를 제공하며, 설정 과정이 매우 간단합니다.
-
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
기존 프로젝트에 추가하는 경우 다음 단계를 따릅니다.
-
필요한 패키지 설치:
tailwindcss
,postcss
,autoprefixer
를 개발 의존성으로 설치합니다.npm install -D tailwindcss postcss autoprefixer # 또는 yarn add -D tailwindcss postcss autoprefixer
-
Tailwind CSS 설정 파일 생성: 다음 명령어를 실행하여 Tailwind CSS 설정 파일을 초기화합니다.
npx tailwindcss init -p
이 명령어는 프로젝트 루트에 두 개의 파일을 생성합니다:
tailwind.config.js
: Tailwind CSS의 기본 설정을 커스터마이징할 수 있는 파일.postcss.config.js
: PostCSS 플러그인을 설정하는 파일 (Tailwind CSS와 Autoprefixer가 포함됨).
-
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: [], };
-
전역 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
(유틸리티 클래스)를 해당 위치에 주입하도록 합니다. -
전역 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 (서버 컴포넌트)
// 클라이언트 컴포넌트를 사용하기 위해 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 (클라이언트 컴포넌트)
"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 (클라이언트 컴포넌트)
"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>
);
}
실습 확인
- 위에서 설명한 Tailwind CSS 설치 및 설정 (
tailwind.config.js
,globals.css
)을 완료합니다. src/app/tailwind-css
폴더를 만들고 위page.tsx
,TailwindButton.tsx
,TailwindCard.tsx
파일을 생성합니다.- 개발 서버(
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를 고려해 보세요.