Tailwind CSS
테일윈드
유틸리티 우선 CSS 프레임워크. 클래스 조합으로 스타일링.
테일윈드
유틸리티 우선 CSS 프레임워크. 클래스 조합으로 스타일링.
Tailwind CSS는 유틸리티 우선(Utility-First) CSS 프레임워크입니다. Bootstrap처럼 미리 정의된 컴포넌트 대신, 작은 유틸리티 클래스를 조합하여 스타일링합니다. HTML에서 직접 디자인하므로 CSS 파일을 별도로 작성할 필요가 거의 없습니다.
핵심 장점은 JIT(Just-in-Time) 컴파일러입니다. 사용한 클래스만 CSS에 포함되어 번들 크기가 작습니다(보통 10KB 미만). 반응형(sm:, md:, lg:), 다크모드(dark:), 상태(hover:, focus:, active:) 변형을 클래스 이름에 직접 작성할 수 있어 개발 속도가 빠릅니다.
Tailwind 4(2024)에서는 설정 파일 없이 CSS 변수로 커스터마이징하는 방식으로 변경되었습니다. 빌드 속도가 10배 향상되고, CSS-first 설정으로 tailwind.config.js 없이도 테마 커스터마이징이 가능합니다. Lightning CSS 엔진 도입으로 PostCSS 의존성도 줄었습니다.
Tailwind는 디자인 시스템과 잘 어울립니다. 색상, 간격, 폰트 등을 미리 정의하고 일관되게 사용할 수 있습니다. Headless UI, Radix UI 같은 로직만 있는 컴포넌트 라이브러리와 조합하면 완전한 커스텀 디자인이 가능합니다.
<!-- Tailwind CSS 기본 사용 -->
<!-- 카드 컴포넌트 -->
<div class="max-w-sm rounded-xl overflow-hidden shadow-lg
bg-white dark:bg-gray-800
hover:shadow-xl transition-shadow">
<img class="w-full h-48 object-cover" src="/image.jpg" alt="...">
<div class="p-6">
<h2 class="text-xl font-bold mb-2
text-gray-900 dark:text-white">
제목
</h2>
<p class="text-gray-600 dark:text-gray-300 text-sm">
설명 텍스트
</p>
</div>
</div>
<!-- 반응형 그리드 -->
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
<!-- 모바일: 1열, 태블릿: 2열, 데스크톱: 3열 -->
<div class="bg-white p-4 rounded-lg">Item 1</div>
<div class="bg-white p-4 rounded-lg">Item 2</div>
<div class="bg-white p-4 rounded-lg">Item 3</div>
</div>
<!-- 버튼 컴포넌트 (React) -->
<button
className={`
px-4 py-2 rounded-lg font-medium
transition-colors duration-200
${variant === 'primary'
? 'bg-blue-600 text-white hover:bg-blue-700 active:bg-blue-800'
: 'bg-gray-200 text-gray-800 hover:bg-gray-300'
}
${disabled ? 'opacity-50 cursor-not-allowed' : ''}
`}
disabled={disabled}
>
{children}
</button>
<!-- Tailwind 4 - CSS-first 설정 -->
<style>
@import "tailwindcss";
/* CSS 변수로 테마 커스터마이징 */
@theme {
--color-primary: #3b82f6;
--color-secondary: #10b981;
--font-display: "Inter", sans-serif;
--breakpoint-3xl: 1920px;
}
</style>
<!-- 재사용 가능한 클래스 추출 (@apply) -->
<style>
.btn-primary {
@apply px-4 py-2 bg-blue-600 text-white rounded-lg
hover:bg-blue-700 active:bg-blue-800
transition-colors duration-200
focus:ring-2 focus:ring-blue-500 focus:ring-offset-2;
}
.input-field {
@apply w-full px-4 py-2 border border-gray-300 rounded-lg
focus:border-blue-500 focus:ring-2 focus:ring-blue-200
dark:bg-gray-800 dark:border-gray-600;
}
</style>
<!-- clsx/tailwind-merge로 조건부 클래스 -->
import { clsx } from 'clsx';
import { twMerge } from 'tailwind-merge';
function cn(...inputs) {
return twMerge(clsx(inputs));
}
<button className={cn(
'px-4 py-2 rounded',
isActive && 'bg-blue-600',
!isActive && 'bg-gray-200',
className // props로 받은 클래스 병합
)}>
기술 선택에서:
"CSS-in-JS 런타임 오버헤드가 싫어요. Tailwind는 빌드 타임에 CSS 생성되니까 런타임 비용 없고, JIT 덕분에 번들도 작아요. 디자인 토큰도 tailwind.config로 관리할 수 있어서 디자인 시스템에도 적합해요."
기술 면접에서:
"Tailwind 단점은 뭐가 있나요?" - "클래스가 길어져서 가독성이 떨어질 수 있어요. @apply로 추출하거나 컴포넌트로 추상화하면 되지만, 팀 컨벤션이 중요합니다. 디자인 변경 시 여러 파일을 수정해야 할 수도 있어요."
코드 리뷰에서:
"클래스가 너무 길어요. 이건 컴포넌트로 빼는 게 좋겠어요." - "맞아요. 3번 이상 반복되거나 의미 단위가 명확하면 컴포넌트로 추출해요. cva(class-variance-authority) 써서 variant 패턴으로 관리하면 더 깔끔해요."