본문 바로가기
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
Tailwind v4에서는 대부분의 테마 설정이 JavaScript 파일을 떠나 CSS로 왔어. design token을 실제로 쓰이는 자리에서 선언하는 방법을 익혀 보자.

테마가 CSS 안으로 들어왔어

Tailwind v3에서는 tailwind.config.js의 JavaScript 객체에 테마를 적었어. v4에서는 메인 CSS의 @theme 블록에 CSS custom property로 선언해. Tailwind 유틸리티와 직접 작성한 CSS가 같은 토큰을 읽으므로 중간 변환 계층이 필요 없어.

토큰 이름이 유틸리티를 만들어

  • --color-*는 배경, 글자, 테두리, ring 색상 유틸리티로 이어져.
  • --font-*는 글꼴, --spacing-*은 padding·margin·gap에 사용돼.
  • --radius-*--shadow-*는 모서리와 그림자 유틸리티를 만들어.
  • --breakpoint-*는 반응형 접두사의 기준이 돼.

예를 들어 --color-brand를 선언하면 bg-brandtext-brand가 그 값을 사용해.

cwkPippa의 방식

cwkPippa의 메인 CSS도 이 구조를 사용해. 기본 다크 테마를 두고 data-theme="light" 선택자에서 같은 토큰 값을 바꿔 밝은 테마를 만들어. 글꼴과 피파 강조 색상도 한 토큰 집합에서 관리해.

JavaScript 설정이 필요한 경우도 있어

플러그인이나 특별한 variant가 필요하면 설정 파일을 사용할 수 있어. 하지만 색, 글꼴, 간격, breakpoint 같은 design token은 CSS에 두는 편이 가장 자연스러워.

토큰의 원본은 한곳에만 둬. 같은 --color-brand@theme, :root, SCSS 변수에 중복해서 선언하지 마. v4에서는 @theme를 원본으로 삼고 나머지가 그 값을 읽게 해.

v3 프로젝트는 서둘러 옮기지 않아도 돼

기존 v3 문법은 호환 경로가 있어 즉시 마이그레이션할 필요가 없어. 다만 새 프로젝트와 새 예제에서는 v4의 CSS-first 구조를 기본으로 삼아.

Code

src/index.css에 Tailwind v4 theme과 다크 모드 설정하기·css
@import "tailwindcss";

@theme {
  /* data-theme 속성이 없을 때는 다크 테마가 기본이야. */
  --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;
}

/* data-theme='light'에서는 필요한 토큰 값만 바꿔. */
[data-theme="light"] {
  --color-bg: #ffffff;
  --color-fg: #1a1a1f;
  --color-bg-elevated: #fafafd;
}

/* 이제 bg-brand, text-fg, font-mono, rounded-card utility를 쓸 수 있어. */
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

부트스트랩 프로젝트의 메인 CSS를 Tailwind v4의 CSS-first 설정으로 완성해. @theme에 success와 warning 색, 본문 font, card radius를 선언하고 유틸리티와 직접 만든 CSS가 같은 토큰을 읽게 해. App에 data-theme를 light와 기본값 사이에서 바꾸는 버튼을 두고 배경과 글자, 포인트 색이 함께 바뀌는지 확인해. 마지막으로 토큰 하나를 바꿔 모든 사용처가 동시에 갱신되는지 봐.
Hint
메인 CSS의 Tailwind import, Vite plugin, main.tsx의 CSS import를 먼저 확인해. 개발 서버뿐 아니라 production build에서도 새 utility가 생성되고 직접 CSS와 같은 값을 쓰는지 검사해.

Progress

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

댓글 0

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

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