Tailwind v3 + v4

Tailwind CSS v3 / v4 듀얼 지원 아키텍처입니다.
컴포넌트 코드는 단일 소스를 유지하고, 테마 파일이 버전 차이를 흡수합니다.
설정 방법은 Installation 페이지를 참고하세요.

듀얼 지원
단일 소스
테마 파일 2개

Architecture

figma-tokens.json → variables.css가 유일한 값 소스입니다. v3-preset.js와 v4-theme.css는 variables.css를 참조하는 매핑 레이어입니다.

Sync Flow
figma-tokens.json
Single Source of Truth
sync-tokens
생성 파일
variables.css
모든 토큰의 HEX 값
light.css
:root
dark.css
.dark
v3-preset.js
JS config + plugins
v4-theme.css
@theme + @utility
유틸리티 제공
컴포넌트 (공통 코드)
bg-primary, text-md, rounded-md ...

v3 동작 방식

  • JS 프리셋 (theme.extend)
  • CSS 변수를 var()로 참조
  • plugins으로 커스텀 유틸리티 정의
  • 시맨틱 컬러 bg-primary/50 지원 (RGB 채널 변수)

v4 동작 방식

  • CSS @theme + @utility
  • var() 참조 + HEX 폴백 (동일 변수명은 캐스케이드로 덮어쓰기)
  • color-mix() 런타임 변환
  • bg-primary/50 지원

Sync Logic

Figma 토큰 → sync-tokens 실행 시, v3/v4 테마 파일이 생성되는 2가지 패턴

1

var() 참조 (변수명이 다른 경우)

테마 변수명과 CSS 변수명이 다를 경우, var()로 직접 참조합니다.

variables.css — 소스
--color-primary-text
var()로 참조
v3/v4 테마 — 별칭으로 정의
--color-primary-foreground
개발자가 사용하는 클래스
text-primary-foreground
v4-theme.css
--color-primary-foreground: var(--color-primary-text)
--text-md: var(--font-size-md)
--color-foreground: var(--color-text)
v3-preset.js
primary.foreground: 'var(--color-primary-text)'
fontSize.md: 'var(--font-size-md)'
foreground: 'var(--color-text)'
2

CSS 캐스케이드 (동일 변수명)

동일 변수명은 var() 자기 참조가 불가합니다. sync-tokens가 v4-theme.css의 @theme에 HEX 폴백 값을 생성하고, variables.css (unlayered)가 @layer theme보다 항상 우선되는 캐스케이드로 덮어씁니다. 유틸리티는 var() 참조를 사용하므로, 다크 모드 변수 전환이 자동 반영됩니다.

CSS Cascade Order
variables.css우선
unlayered — 캐스케이드에서 항상 우선
↑ 덮어쓰기
v4-theme.csstheme layer
@theme — HEX 폴백 값
v4-theme.css (@theme = theme layer)
--color-primary: #15A0AC /* /* 폴백 */ */
--color-border: #E4E4E7
--radius-md: 6px
variables.css (unlayered = 항상 우선)
--color-primary: #15A0AC /* /* 우선 */ */
--color-border: #E4E4E7
--radius-md: 6px
variables.css
var() 참조
var(--color-primary-text)
변수명이 다를 때
Colors (-foreground)Typography
CSS 캐스케이드
#15A0AC → unlayered override
동일 변수명
Colors (primary, etc.)RadiusShadow
@utility / plugins
@utility { ... var(...) }
@theme에 없는 항목
DurationScaleZ-indexIcon

이 동기화 작업들은 sync-tokens CLI로 자동 생성됩니다. v3-preset.js / v4-theme.css를 직접 편집할 필요가 없습니다.

Naming Differences

v3과 v4는 테마 변수 정의 방식이 다릅니다. 컴포넌트가 사용하는 유틸리티 클래스는 동일합니다.

text-md
v3fontSize: { md: ['var(--font-size-md)', ...] }
v4--text-md: var(--font-size-md)
bg-primary
v3colors: { primary: 'var(--color-primary)' }
v4--color-primary: #15A0AC (cascade)
rounded-md
v3borderRadius: { md: 'var(--radius-md)' }
v4--radius-md: 6px (cascade)
text-foreground
v3colors: { foreground: 'var(--color-text)' }
v4--color-foreground: var(--color-text)
shadow-sm
v3boxShadow: { sm: 'var(--shadow-sm)' }
v4--shadow-sm: 0 1px 3px ... (cascade)
border-border
v3colors: { border: 'var(--color-border)' }
v4--color-border: #E4E4E7 (cascade)
icon-xs ~ xl
v3addUtilities plugin
v4@utility { width/height: var(...) }

v4의 @theme 네임스페이스에 없는 항목(duration, scale, z-index, icon-size 등)은 @utility으로 개별 정의합니다. v3에서는 동등한 기능을 pluginsaddUtilities()으로 구현합니다.

v4에서는 *-foreground 별칭도 사용 가능합니다 (예: text-muted-foreground = text-text-muted). shadcn/ui 등의 에코시스템과 호환됩니다.

Custom Utilities

Tailwind 표준 테마에 없는 항목을 v3/v4 각각의 방식으로 커스텀 유틸리티로 정의합니다.

Duration

duration-micro, duration-fast, duration-normal

트랜지션 지속 시간

Scale

scale-pressed

버튼 클릭 시 축소 애니메이션

Icon Sizes

icon-xs ~ icon-xl

5단계 아이콘 크기

Focus Ring

focus-ring

포커스 링 유틸리티

Z-index

z-modal, z-tooltip, z-toast

명명된 Z-인덱스 레이어

Animation

animate-checkbox-enter, animate-accordion-down

컴포넌트 애니메이션

v4 — @utility (v4-theme.css에 정의)
duration-micro
transition-duration: var(--duration-micro)
icon-xs
width / height: var(--icon-size-xs)
focus-ring
box-shadow: 0 0 0 2px var(--color-focus-ring)
v3 — plugins (v3-preset.js에 정의)
.duration-micro
transition-duration: var(--duration-micro)
.icon-xs
width / height: var(--icon-size-xs)
.focus-ring
box-shadow: 0 0 0 2px var(--color-focus-ring)

Dark Mode

다크 모드는 themes/dark.css의 .dark 블록으로 완전히 관리됩니다. v3/v4 테마 파일에 다크 모드 정의가 필요 없습니다.

Light:root
background
text
primary
Dark.dark
background
text
primary
.dark 클래스 전환으로 외관이 자동으로 바뀝니다 — primary 등의 컬러는 dark.css에서 톤 조정 가능

v3

사용자의 tailwind.config.js에 darkMode: ['class']를 설정합니다.v3-preset.js는 var()로 참조하므로,.dark 클래스로 변수가 전환되면 자동으로 반영됩니다.

v4

variables.css (unlayered)가 @theme (theme layer)를 캐스케이드로 항상 덮어씁니다. 유틸리티는 var()를 사용하므로, .dark 변수 전환이 자동 반영됩니다.v4-theme.css에 .dark 블록은 필요 없습니다.

Opacity Modifier

v3/v4 모두 bg-primary/50 같은 opacity modifier를 지원합니다. v3은 RGB 채널 변수, v4는 color-mix()로 구현됩니다.

100%
75%
50%
25%
10%

v3

RGB 채널 변수로 완전 지원
bg-primary
bg-primary/50
text-foreground/80
border-border/50

v4

color-mix()로 완전 지원
bg-primary
bg-primary/50
text-foreground/80
border-border/50

v3에서도 bg-primary/50 같은 opacity modifier를 지원합니다.RGB 채널 변수(--color-*-rgb)를 자동 생성하고 <alpha-value>를 적용합니다.