Tailwind CSS v4: CSS-First 설정과 새로운 기능 완전 가이드

프론트엔드

Tailwind CSS v4CSS디자인 시스템유틸리티 CSS마이그레이션

이 글은 누구를 위한 것인가

  • Tailwind CSS v4의 변경사항을 파악하고 마이그레이션을 계획하는 팀
  • @theme으로 디자인 토큰을 관리하고 싶은 개발자
  • CSS-first 설정으로 tailwind.config.js 없이 Tailwind를 설정하려는 팀

들어가며

Tailwind CSS v4는 설정 방식을 완전히 바꿨다. JavaScript 설정 파일 대신 CSS 파일에서 @theme으로 설정하고, @import 'tailwindcss' 한 줄로 시작한다. LightningCSS 기반으로 빌드 속도가 5-10배 빨라졌다.

이 글은 bluefoxdev.kr의 Tailwind v4 완전 가이드 를 참고하여 작성했습니다.


1. Tailwind v4 핵심 변경사항

[v3 vs v4 비교]

설정 파일:
  v3: tailwind.config.js (JS 파일)
  v4: CSS 파일 내 @theme (JS 불필요)

콘텐츠 감지:
  v3: content: ['./src/**/*.tsx'] 명시
  v4: 자동 감지 (설정 불필요)

임포트:
  v3: @tailwind base; @tailwind components; @tailwind utilities;
  v4: @import 'tailwindcss'; (한 줄)

빌드 엔진:
  v3: PostCSS + autoprefixer
  v4: LightningCSS (5-10x 빠름)

새 유틸리티:
  text-shadow-*: 텍스트 그림자
  mask-image-*: 마스크 이미지
  interpolate-size: 높이 애니메이션
  starting-style: 마운트 애니메이션

CSS 변수:
  v3: var(--tw-color-blue-500) (없음, 직접 접근 불가)
  v4: var(--color-blue-500) (모든 토큰 CSS 변수로 노출)

2. Tailwind v4 설정과 마이그레이션

/* app/globals.css - v4 설정 */
@import 'tailwindcss';

/* @theme: 디자인 토큰 정의 (v3의 tailwind.config.js 대체) */
@theme {
  /* 색상 */
  --color-brand-50:  oklch(97% 0.01 260);
  --color-brand-500: oklch(55% 0.18 260);
  --color-brand-900: oklch(25% 0.10 260);
  
  /* 폰트 */
  --font-sans: 'Pretendard Variable', system-ui, sans-serif;
  --font-mono: 'JetBrains Mono', monospace;
  
  /* 간격 오버라이드 */
  --spacing-18: 4.5rem;
  --spacing-22: 5.5rem;
  
  /* 반응형 브레이크포인트 */
  --breakpoint-xs: 480px;
  --breakpoint-3xl: 1920px;
  
  /* 애니메이션 */
  --animate-wiggle: wiggle 0.3s ease-in-out infinite;
  
  /* 그림자 */
  --shadow-glow: 0 0 20px oklch(55% 0.18 260 / 50%);
}

/* 커스텀 애니메이션 */
@keyframes wiggle {
  0%, 100% { transform: rotate(-3deg); }
  50% { transform: rotate(3deg); }
}

/* 커스텀 유틸리티 */
@utility scrollbar-hide {
  scrollbar-width: none;
  &::-webkit-scrollbar { display: none; }
}

/* 미디어 쿼리 변형 */
@variant dark (&:is(.dark *));
@variant hocus (&:hover, &:focus-visible);
<!-- v4 새 유틸리티 사용 -->

<!-- text-shadow (v4 신규) -->
<h1 class="text-shadow-lg text-shadow-brand-500/30">
  빛나는 제목
</h1>

<!-- mask-image (v4 신규) -->
<div class="mask-image-[linear-gradient(to_bottom,black_70%,transparent)]">
  페이드 아웃 콘텐츠
</div>

<!-- interpolate-size: 높이 0 → auto 애니메이션 가능 -->
<details class="[interpolate-size:allow-keywords]">
  <summary>더 보기</summary>
  <div class="h-0 overflow-hidden transition-[height] open:h-auto">
    감춰진 콘텐츠
  </div>
</details>

<!-- @starting-style 지원 (마운트 애니메이션) -->
<div class="transition-opacity starting:opacity-0">
  페이드 인 요소
</div>

<!-- 임의 값 (v3와 동일) -->
<div class="mt-[17px] bg-[oklch(55%_0.18_260)] text-[clamp(1rem,3vw,2rem)]">

<!-- CSS 변수 직접 참조 (v4 신규) -->
<div class="bg-[--color-brand-500]">
  테마 색상 사용
</div>

<!-- 새 컨테이너 쿼리 유틸리티 -->
<div class="@container">
  <div class="@sm:grid-cols-2 @lg:grid-cols-3">
    컨테이너 쿼리 반응형
  </div>
</div>
// v3 → v4 마이그레이션 자동화
// npx @tailwindcss/upgrade@next

// 주요 변경 사항:
// tailwind.config.js → globals.css @theme
// v3 클래스 이름 변경:
//   shadow-sm → shadow-xs
//   shadow     → shadow-sm
//   ring-offset-* → ring-offset (통합됨)
//   flex-shrink → shrink
//   overflow-ellipsis → text-ellipsis

// v3 config → v4 CSS 변환 예시
// v3 tailwind.config.js:
// module.exports = {
//   theme: {
//     extend: {
//       colors: { brand: { 500: '#6366f1' } },
//       fontFamily: { sans: ['Pretendard', 'sans-serif'] },
//     },
//   },
// };

// v4 globals.css:
// @theme {
//   --color-brand-500: #6366f1;
//   --font-sans: 'Pretendard', sans-serif;
// }
/* 고급 패턴 - v4 레이어 */

/* 컴포넌트 레이어 */
@layer components {
  .btn {
    @apply inline-flex items-center px-4 py-2 rounded-lg font-medium;
    @apply transition-colors focus-visible:outline-2 focus-visible:outline-offset-2;
  }
  
  .btn-primary {
    @apply btn bg-brand-500 text-white hover:bg-brand-600;
    @apply focus-visible:outline-brand-500;
  }
}

/* 플러그인 없이 변형 정의 */
@variant print {
  @media print {
    &;
  }
}

/* 사용: class="print:hidden" */

/* 다크모드: CSS 변수로 토큰 교체 */
.dark {
  --color-bg: oklch(15% 0.01 260);
  --color-text: oklch(95% 0.01 260);
  --color-surface: oklch(20% 0.01 260);
}

/* 유틸리티 생성 */
@utility container-fluid {
  width: 100%;
  max-width: var(--breakpoint-2xl, 1536px);
  margin-inline: auto;
  padding-inline: var(--spacing-4);
}

마무리

Tailwind v4의 CSS-first 접근은 설정 복잡도를 크게 줄인다. @theme에서 CSS 변수로 정의된 모든 토큰은 var(--color-brand-500)으로 직접 접근할 수 있어 CSS와 Tailwind 사이의 경계가 사라진다. 마이그레이션은 npx @tailwindcss/upgrade 자동화 도구로 대부분의 변환이 가능하지만, 커스텀 플러그인과 임의의 구성은 수동 검토가 필요하다.