C.W.K.
Stream
Lesson 05 of 07 · published

Tailwind v4 — CSS-First 셋업

~15 min · tailwind, v4, theme, css-variables

Level 0React 입문자
0 XP0/54 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete
v3 → v4 가 Tailwind 가 출하한 가장 큰 변화야. 대부분 프로젝트에서 JS config 파일이 사라졌어. design token 이 원래 살아야 할 자리 — CSS 안 — 으로 돌아왔어.

뭐가 바뀐 거

v3 에선 테마가 tailwind.config.js 안 JavaScript object 였어. Tailwind 가 읽어서 내부적으로 CSS 변수 생성하고 유틸리티 emit. 본인 CSS 에서 테마 토큰 참조하기가 어려웠어.

v4 에선 테마가 CSS 안 @theme 선언으로 존재. Tailwind 가 평범한 CSS 변수로 읽어. 유틸리티 동작 방식은 같음 (bg-brand--color-brand 읽음). 차이점: 본인 CSS 도 그 변수 읽을 수 있음. 브리지 레이어 없음.

@theme 블록

@theme 안에 CSS custom property 선언. Tailwind 가 유틸리티 패밀리에 매핑되는 prefix 몇 개 예약:

  • --color-*bg-*, text-*, border-*, ring-*
  • --font-*font-*
  • --spacing-*p-*, m-*, gap-*
  • --radius-*rounded-*
  • --shadow-*shadow-*
  • --breakpoint-*sm:, md:

토큰 선언하면 유틸리티 등장. 재시작 없음, 챙겨야 할 컴파일 단계 없음.

cwkPippa 패턴

cwkPippa 의 frontend/src/index.css 가 v4 모델 써. Dark mode 가 [data-theme='light'] selector 로 키 (기본 다크, attribute 스위치로 밝아짐). Font 토큰은 sans 에 Inter, code 에 JetBrains Mono. accent 컬러는 당연히 Pippa-pink.

Eject 안 하고 커스터마이즈

JS 플러그인 (예: custom variant) 필요하면 여전히 config 파일로 탈출 가능. 하지만 design token — 색, 폰트, 간격, breakpoint — 은 순수 CSS 가 길.

단일 진실 원점. --color-brand@theme + 별도 :root 블록 + 다른 곳의 SCSS 변수에 동시에 정의하지 마. 하나의 집을 골라. v4 의 요점이 @theme 가 그 집 — 모두 거기서 흐른다.

v3 사용자를 위한 마이그레이션 노트

기존 v3 프로젝트가 즉시 갈아탈 필요 없어. v3 문법 (@tailwind base; 등) 이 호환성 위해 v4 에서도 동작. 다만 새 프로젝트, 새 레슨, 새 예제는 v4-네이티브여야 해. 이 퀘스트는 처음부터 끝까지 v4-네이티브.

Code

src/index.css — 테마 토큰 + dark mode 포함 v4 풀 셋업·css
@import "tailwindcss";

@theme {
  /* Dark mode 가 디폴트 ([data-theme] attribute 없는 상태) */
  --color-bg: #0d0d12;
  --color-bg-elevated: #16161e;
  --color-fg: #e8e8ee;
  --color-muted: #9b9bab;

  --color-brand: #FF8FBE;
  --color-brand-strong: #d62e84;

  --font-sans: "Inter", system-ui, sans-serif;
  --font-mono: "JetBrains Mono", ui-monospace, monospace;

  --radius-card: 0.75rem;
}

/* Light mode: [data-theme='light'] 설정 시 변수 몇 개 교체 */
[data-theme="light"] {
  --color-bg: #ffffff;
  --color-fg: #1a1a1f;
  --color-bg-elevated: #fafafd;
}

/* 이제 `bg-brand`, `text-fg`, `font-mono`, `rounded-card` 다 동작. */
html, body {
  background: var(--color-bg);
  color: var(--color-fg);
  font-family: var(--font-sans);
}
유틸리티로 테마 토큰 쓰는 컴포넌트·tsx
// 아래 모든 클래스가 위 @theme 의 변수에 매핑돼.
export function ConversationCard({ title }: { title: string }) {
  return (
    <article className="bg-bg-elevated text-fg font-sans rounded-card p-4 shadow-sm hover:shadow-md transition-shadow">
      <h3 className="font-medium text-brand">{title}</h3>
      <p className="text-sm text-muted mt-1">Click to open</p>
    </article>
  );
}

External links

Exercise

Bootstrap 프로젝트에서 src/index.css 를 위 v4 셋업으로 교체. 커스텀 색 두 개 (--color-success, --color-warning) 추가하고 보이는 엘리먼트에 bg-success + text-warning 써서 동작 증명. 그다음 App.tsx 상단에 버튼 추가해서 document.documentElementdata-theme attribute 를 부재/"light" 토글 — 페이지 배경이 뒤집히는지 확인.
Hint
토글: document.documentElement.setAttribute('data-theme', current === 'light' ? '' : 'light'). 현재 테마는 useState 로 추적. 이 패턴은 Track 4 lesson 2 에서 정식화할 거야.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.