🌐 웹개발

Tailwind 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 패턴으로 관리하면 더 깔끔해요."

⚠️ 주의사항

🔗 관련 용어

CSS-in-JS PostCSS Design System Radix UI Responsive Design

📚 더 배우기

📄 Tailwind CSS 공식 문서 📄 Tailwind UI - 공식 컴포넌트 📄 CVA - Class Variance Authority