본문으로 건너뛰기
Kreath Archive
TechProjectsBooksAbout
TechProjectsBooksAbout

내비게이션

  • Tech
  • Projects
  • Books
  • About
  • Tags

카테고리

  • AI / ML
  • 웹 개발
  • 프로그래밍
  • 개발 도구

연결

  • GitHub
  • Email
  • RSS
© 2026 Kreath Archive. All rights reserved.Built with Next.js + MDX
홈TechProjectsBooksAbout
//
  1. 홈
  2. 테크
  3. 2장: CSS-first 설정과 @theme 디렉티브
2026년 2월 17일·웹 개발·

2장: CSS-first 설정과 @theme 디렉티브

Tailwind CSS v4의 핵심 설정 방식인 @theme 디렉티브를 심층 분석합니다. 디자인 토큰 정의, 네임스페이스 규칙, 기본 테마 확장과 재정의 패턴을 다룹니다.

11분624자6개 섹션
frontend
공유
tailwind-v42 / 11
1234567891011
이전1장: Tailwind CSS v4 소개 — 패러다임의 전환다음3장: 새로운 임포트 구조와 레이어 시스템

1장에서 Tailwind CSS v4의 전체적인 변화를 조망했습니다. 이 장에서는 v4의 가장 핵심적인 변화인 CSS-first 설정을 깊이 파고듭니다. tailwind.config.js를 대체하는 @theme 디렉티브의 동작 원리, 네임스페이스 규칙, 기본 테마와의 관계를 상세히 다룹니다.

tailwind.config.js에서 @theme으로

v3의 설정 방식

v3에서는 JavaScript 객체로 모든 디자인 토큰을 정의했습니다.

v3: tailwind.config.js
javascript
module.exports = {
  theme: {
    colors: {
      primary: '#3b82f6',
      secondary: '#64748b',
    },
    extend: {
      spacing: {
        '18': '4.5rem',
        '22': '5.5rem',
      },
      fontFamily: {
        sans: ['Pretendard', 'system-ui', 'sans-serif'],
      },
    },
  },
}

이 방식은 JavaScript의 표현력을 활용할 수 있었지만, CSS 도구와의 통합에 제약이 있었습니다. IDE의 CSS 자동완성, CSS 변수 참조, 런타임 테마 전환 등에서 추가적인 도구가 필요했습니다.

v4의 CSS-first 설정

v4에서는 모든 설정이 CSS 파일 안에서 이루어집니다.

v4: globals.css
css
@import "tailwindcss";
 
@theme {
  --color-primary: #3b82f6;
  --color-secondary: #64748b;
 
  --spacing-18: 4.5rem;
  --spacing-22: 5.5rem;
 
  --font-sans: "Pretendard", system-ui, sans-serif;
}
Info

@theme 블록에서 정의한 변수는 두 가지 역할을 동시에 수행합니다. 첫째, CSS 커스텀 프로퍼티로 출력되어 런타임에 참조할 수 있습니다. 둘째, Tailwind가 해당 값에 대응하는 유틸리티 클래스를 자동 생성합니다.

@theme의 네임스페이스

@theme 안의 변수명은 특정 접두사를 따라야 합니다. 이 접두사가 어떤 유틸리티 클래스를 생성할지 결정합니다.

색상 (--color-*)

색상 네임스페이스
css
@theme {
  --color-brand: #3b82f6;
  --color-brand-light: #93c5fd;
  --color-brand-dark: #1d4ed8;
 
  --color-surface: #ffffff;
  --color-surface-alt: #f8fafc;
 
  --color-success: #22c55e;
  --color-warning: #f59e0b;
  --color-error: #ef4444;
}

이 정의로 다음 유틸리티가 자동 생성됩니다.

html
<!-- 배경 -->
<div class="bg-brand bg-brand-light bg-surface"></div>
 
<!-- 텍스트 -->
<p class="text-brand text-error"></p>
 
<!-- 테두리 -->
<div class="border-brand-dark"></div>
 
<!-- 그라데이션 -->
<div class="from-brand to-brand-light"></div>
 
<!-- 투명도와 결합 -->
<div class="bg-brand/50"></div>

간격 (--spacing-*)

간격 네임스페이스
css
@theme {
  --spacing-0: 0;
  --spacing-1: 0.25rem;
  --spacing-2: 0.5rem;
  --spacing-4: 1rem;
  --spacing-8: 2rem;
  --spacing-header: 4rem;
  --spacing-sidebar: 16rem;
}

간격 토큰은 margin, padding, gap, width, height, inset 등 다양한 유틸리티에서 사용됩니다.

html
<div class="p-header m-sidebar gap-4 w-sidebar"></div>

글꼴 (--font-*)

글꼴 네임스페이스
css
@theme {
  --font-sans: "Pretendard Variable", system-ui, sans-serif;
  --font-serif: "Noto Serif KR", Georgia, serif;
  --font-mono: "JetBrains Mono", "Fira Code", monospace;
  --font-display: "Pretendard Variable", system-ui, sans-serif;
}
html
<p class="font-sans">본문 텍스트</p>
<h1 class="font-display">제목 텍스트</h1>
<code class="font-mono">코드 텍스트</code>

글꼴 크기 (--text-*)

글꼴 크기
css
@theme {
  --text-xs: 0.75rem;
  --text-xs--line-height: 1rem;
 
  --text-sm: 0.875rem;
  --text-sm--line-height: 1.25rem;
 
  --text-base: 1rem;
  --text-base--line-height: 1.5rem;
 
  --text-lg: 1.125rem;
  --text-lg--line-height: 1.75rem;
}

--text-*--line-height 형식으로 해당 크기에 대응하는 행간을 함께 정의할 수 있습니다.

브레이크포인트 (--breakpoint-*)

브레이크포인트
css
@theme {
  --breakpoint-sm: 640px;
  --breakpoint-md: 768px;
  --breakpoint-lg: 1024px;
  --breakpoint-xl: 1280px;
  --breakpoint-2xl: 1536px;
}
html
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3"></div>

그림자 (--shadow-*)

그림자
css
@theme {
  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
  --shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
  --shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
  --shadow-card: 0 2px 8px -2px rgb(0 0 0 / 0.08);
}
html
<div class="shadow-card hover:shadow-lg"></div>

애니메이션 (--animate-*)

애니메이션
css
@theme {
  --animate-fade-in: fade-in 0.3s ease-out;
  --animate-slide-up: slide-up 0.4s ease-out;
  --animate-spin: spin 1s linear infinite;
}
 
@keyframes fade-in {
  from { opacity: 0; }
  to { opacity: 1; }
}
 
@keyframes slide-up {
  from { opacity: 0; transform: translateY(1rem); }
  to { opacity: 1; transform: translateY(0); }
}
html
<div class="animate-fade-in"></div>
<div class="animate-slide-up"></div>

둥근 모서리 (--radius-*)

둥근 모서리
css
@theme {
  --radius-sm: 0.25rem;
  --radius-md: 0.375rem;
  --radius-lg: 0.5rem;
  --radius-xl: 0.75rem;
  --radius-2xl: 1rem;
  --radius-full: 9999px;
}
html
<div class="rounded-lg"></div>
<button class="rounded-full"></button>

기본 테마 확장과 재정의

기본값 유지하며 확장

@theme에서 정의한 토큰은 기본 테마에 추가됩니다. Tailwind의 기본 색상(slate, gray, blue 등)과 기본 간격은 그대로 유지됩니다.

기본 테마 확장
css
@import "tailwindcss";
 
@theme {
  /* 기본 색상은 유지되고, brand가 추가됨 */
  --color-brand: oklch(0.6 0.2 250);
}

기본값 재정의

특정 네임스페이스의 기본값을 완전히 제거하고 싶다면, --color-*: initial처럼 와일드카드 초기화를 사용합니다.

기본값 초기화 후 재정의
css
@import "tailwindcss";
 
@theme {
  /* 기본 색상 팔레트 전체 제거 */
  --color-*: initial;
 
  /* 프로젝트 전용 색상만 정의 */
  --color-primary: oklch(0.6 0.2 250);
  --color-secondary: oklch(0.7 0.15 180);
  --color-neutral-50: oklch(0.985 0 0);
  --color-neutral-100: oklch(0.97 0 0);
  --color-neutral-900: oklch(0.21 0 0);
  --color-neutral-950: oklch(0.13 0 0);
}
Warning

--color-*: initial을 사용하면 Tailwind 기본 제공 색상(slate, gray, zinc, blue 등)이 모두 제거됩니다. 필요한 색상은 직접 정의해야 합니다. 프로젝트 초반에 결정하는 것이 좋으며, 이미 기본 색상을 사용 중인 코드가 있다면 주의가 필요합니다.

인라인 @theme

특정 네임스페이스만 초기화하면서 동시에 새 값을 정의하려면, @theme inline 옵션을 사용할 수 있습니다.

@theme inline
css
@theme inline {
  --color-primary: oklch(0.6 0.2 250);
  --color-secondary: oklch(0.7 0.15 180);
}

inline 키워드는 해당 테마 변수를 CSS 커스텀 프로퍼티로 출력하지 않고, 유틸리티 생성에만 사용합니다. 이는 출력 CSS 크기를 줄이고 싶을 때 유용합니다.

복합 네임스페이스 패턴

의미론적 토큰 계층

v3에서 colors.primary.DEFAULT, colors.primary.light 등으로 표현했던 패턴을 v4에서는 - 구분자로 표현합니다.

의미론적 색상 계층
css
@theme {
  /* 원시 색상 팔레트 */
  --color-blue-50: oklch(0.97 0.01 250);
  --color-blue-100: oklch(0.94 0.03 250);
  --color-blue-500: oklch(0.62 0.21 250);
  --color-blue-600: oklch(0.55 0.22 250);
  --color-blue-900: oklch(0.28 0.12 250);
 
  /* 의미론적 매핑 */
  --color-primary: var(--color-blue-500);
  --color-primary-hover: var(--color-blue-600);
  --color-primary-foreground: white;
}
html
<button class="bg-primary hover:bg-primary-hover text-primary-foreground">
  버튼 텍스트
</button>

컴포넌트 토큰

컴포넌트 수준 토큰
css
@theme {
  /* 카드 컴포넌트 토큰 */
  --color-card: var(--color-surface);
  --color-card-foreground: var(--color-neutral-900);
 
  --shadow-card: 0 2px 8px -2px rgb(0 0 0 / 0.08);
  --radius-card: var(--radius-lg);
 
  /* 입력 컴포넌트 토큰 */
  --color-input: var(--color-neutral-100);
  --color-input-border: var(--color-neutral-300);
  --color-input-focus: var(--color-primary);
}
Tip

의미론적 토큰 계층을 설계할 때는 원시 토큰(Primitive) → 의미론적 토큰(Semantic) → 컴포넌트 토큰(Component) 순서로 계층화하세요. 이렇게 하면 테마 변경 시 의미론적 레벨만 수정하면 전체 UI가 일관되게 업데이트됩니다.

@theme 외부의 CSS 커스텀 프로퍼티

@theme 밖에서 정의한 CSS 커스텀 프로퍼티는 유틸리티 클래스를 생성하지 않지만, @theme 내부에서 참조할 수 있습니다.

@theme과 CSS 변수 결합
css
:root {
  --brand-hue: 250;
  --brand-saturation: 0.2;
}
 
@theme {
  --color-brand: oklch(0.6 var(--brand-saturation) var(--brand-hue));
  --color-brand-light: oklch(0.8 var(--brand-saturation) var(--brand-hue));
  --color-brand-dark: oklch(0.4 var(--brand-saturation) var(--brand-hue));
}

이 패턴은 JavaScript에서 --brand-hue 값을 동적으로 변경하여 런타임 테마 전환을 구현할 때 유용합니다.

정리

@theme 디렉티브는 Tailwind CSS v4의 설계 철학을 가장 잘 보여주는 기능입니다. JavaScript 설정 파일의 복잡성을 CSS의 선언적 구문으로 대체하면서도, 디자인 토큰에서 유틸리티 클래스까지의 자동 생성 파이프라인은 그대로 유지합니다. 네임스페이스 규칙을 이해하면 색상, 간격, 글꼴, 그림자 등 모든 디자인 토큰을 CSS 안에서 일관되게 관리할 수 있습니다.

다음 장에서는 v4의 새로운 임포트 구조와 CSS 레이어 시스템을 상세히 다룹니다. @layer, @utility, 그리고 커스텀 유틸리티 정의 방식을 배웁니다.

이 글이 도움이 되셨나요?

관련 주제 더 보기

#frontend

관련 글

웹 개발

3장: 새로운 임포트 구조와 레이어 시스템

Tailwind CSS v4의 임포트 방식, CSS 레이어 시스템, @utility로 커스텀 유틸리티 정의하기, 그리고 스타일 우선순위 관리 전략을 다룹니다.

2026년 2월 19일·11분
웹 개발

1장: Tailwind CSS v4 소개 — 패러다임의 전환

Tailwind CSS v4의 핵심 변경사항과 아키텍처 혁신을 조망합니다. Rust 기반 엔진, CSS-first 설정, 새로운 임포트 구조 등 v3에서 v4로의 패러다임 전환을 이해합니다.

2026년 2월 15일·11분
웹 개발

4장: OKLCH 색상 시스템과 색상 유틸리티

Tailwind CSS v4의 기본 색상 시스템인 OKLCH의 원리, 장점, 색상 팔레트 설계 방법, 그리고 투명도 수정자와 색상 조합 패턴을 실전 중심으로 다룹니다.

2026년 2월 21일·12분
이전 글1장: Tailwind CSS v4 소개 — 패러다임의 전환
다음 글3장: 새로운 임포트 구조와 레이어 시스템

댓글

목차

약 11분 남음
  • tailwind.config.js에서 @theme으로
    • v3의 설정 방식
    • v4의 CSS-first 설정
  • @theme의 네임스페이스
    • 색상 (--color-*)
    • 간격 (--spacing-*)
    • 글꼴 (--font-*)
    • 글꼴 크기 (--text-*)
    • 브레이크포인트 (--breakpoint-*)
    • 그림자 (--shadow-*)
    • 애니메이션 (--animate-*)
    • 둥근 모서리 (--radius-*)
  • 기본 테마 확장과 재정의
    • 기본값 유지하며 확장
    • 기본값 재정의
    • 인라인 @theme
  • 복합 네임스페이스 패턴
    • 의미론적 토큰 계층
    • 컴포넌트 토큰
  • @theme 외부의 CSS 커스텀 프로퍼티
  • 정리