[React] Tailwind CSS
개요
Tailwind CSS는 미리 정의된 유틸리티 클래스를 조합해 스타일을 지정하는 CSS 프레임워크입니다. 별도의 CSS 파일을 만들지 않고 HTML(JSX)에 클래스만 추가하면 스타일이 적용됩니다.
설치 (Vite + React)
npm install -D tailwindcss @tailwindcss/vite
// vite.config.ts
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import tailwindcss from "@tailwindcss/vite";
export default defineConfig({
plugins: [react(), tailwindcss()],
});
/* src/index.css */
@import "tailwindcss";
유틸리티 클래스 개념
CSS 속성 하나가 클래스 하나입니다.
// ❌ 전통 방식: CSS 파일 따로 작성
<div className="card">
<h1 className="title">안녕하세요</h1>
</div>
// ✅ Tailwind 방식: 클래스만으로 스타일 완성
<div className="bg-white rounded-lg shadow-md p-6">
<h1 className="text-2xl font-bold text-gray-800">안녕하세요</h1>
</div>
자주 쓰는 클래스 목록
레이아웃
// Flexbox
<div className="flex items-center justify-between gap-4">
// Grid
<div className="grid grid-cols-3 gap-4">
// 컨테이너
<div className="max-w-4xl mx-auto px-4">
간격 (Spacing)
// padding: p(4방향) px(좌우) py(상하) pt(위) pb(아래) pl(왼) pr(오른)
<div className="p-4 px-6 py-2 pt-8">
// margin
<div className="m-4 mt-2 mb-4 mx-auto">
텍스트
<p className="text-sm text-base text-lg text-xl text-2xl">크기</p>
<p className="font-normal font-medium font-semibold font-bold">굵기</p>
<p className="text-gray-500 text-blue-600 text-red-500">색상</p>
<p className="text-left text-center text-right">정렬</p>
색상 & 배경
<div className="bg-white bg-gray-100 bg-blue-500">배경</div>
<div className="border border-gray-200 border-2 border-blue-500">테두리</div>
크기
<div className="w-full w-1/2 w-64 h-12 h-screen min-h-0 max-w-sm">
둥근 모서리 & 그림자
<div className="rounded rounded-lg rounded-full rounded-none">
<div className="shadow shadow-md shadow-lg shadow-xl">
반응형 디자인
클래스 앞에 브레이크포인트 접두사를 붙입니다.
| 접두사 | 화면 너비 |
|---|---|
| (없음) | 모바일 (0px~) |
sm: |
640px~ |
md: |
768px~ |
lg: |
1024px~ |
xl: |
1280px~ |
// 모바일: 1열 / 태블릿: 2열 / 데스크톱: 4열
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">
{items.map((item) => <Card key={item.id} {...item} />)}
</div>
// 모바일: 숨김 / 데스크톱: 표시
<nav className="hidden lg:block">
조건부 스타일 (clsx)
npm install clsx
import { clsx } from "clsx";
interface ButtonProps {
variant?: "primary" | "secondary" | "danger";
disabled?: boolean;
children: React.ReactNode;
onClick?: () => void;
}
function Button({ variant = "primary", disabled, children, onClick }: ButtonProps) {
return (
<button
onClick={onClick}
disabled={disabled}
className={clsx(
"px-4 py-2 rounded font-medium transition-colors", // 공통 클래스
{
"bg-blue-500 text-white hover:bg-blue-600": variant === "primary",
"bg-gray-200 text-gray-800 hover:bg-gray-300": variant === "secondary",
"bg-red-500 text-white hover:bg-red-600": variant === "danger",
"opacity-50 cursor-not-allowed": disabled,
}
)}
>
{children}
</button>
);
}
카드 컴포넌트 예시
interface CardProps {
title: string;
description: string;
imageUrl?: string;
tag: string;
}
function Card({ title, description, imageUrl, tag }: CardProps) {
return (
<div className="bg-white rounded-xl shadow-md overflow-hidden hover:shadow-lg transition-shadow">
{imageUrl && (
<img src={imageUrl} alt={title} className="w-full h-48 object-cover" />
)}
<div className="p-6">
<span className="text-xs font-semibold text-blue-500 uppercase tracking-wide">
{tag}
</span>
<h2 className="mt-2 text-xl font-bold text-gray-900">{title}</h2>
<p className="mt-2 text-gray-600 text-sm line-clamp-3">{description}</p>
</div>
</div>
);
}
다크 모드
// tailwind.config에서 darkMode: 'class' 설정 후
<div className="bg-white dark:bg-gray-900 text-gray-900 dark:text-white">
<p className="text-gray-600 dark:text-gray-400">내용</p>
</div>
// html에 class="dark" 추가로 전환
document.documentElement.classList.toggle("dark");