디자인 트렌드

Tailwind CSS 색상 시스템: 쉐이드는 어떻게 생성되는가

6분 읽기

Tailwind CSS는 웹 개발에서 가장 널리 사용되는 색상 시스템 중 하나를 탑재합니다. 50에서 950까지 11개의 쉐이드로 나뉜 22개 색상 패밀리로 구성된 팔레트는 수백만 개의 웹사이트를 구동하며, 개발자들이 색상 스케일을 생각하는 방식의 사실상 표준이 되었습니다. 이 쉐이드들은 어디서 오는 것일까요? 어떻게 생성되고, 시스템에 매끄럽게 맞는 자신만의 스케일은 어떻게 만들 수 있을까요? 이 글이 그 모든 질문에 답합니다.

색상에 대한 Tailwind의 디자인 철학

Tailwind는 쉐이드 생성에 단순한 산술적 접근 방식을 사용하지 않습니다. 대신 Tailwind 팀은 지각적 명도와 미적 판단의 조합을 활용하여 원본 팔레트의 모든 쉐이드를 직접 큐레이션했습니다. 목표는 다음과 같은 쉐이드를 만드는 것이었습니다:

  1. 모든 단계에서 유용할 것: 50에서 950까지의 각 쉐이드는 누군가 실제로 사용하고 싶어할 법한 색이어야 합니다. 결국 사용되지 않는 간격 채우기 색이 되어서는 안 됩니다.
  2. 색조 전반에서 일관성 있을 것: 파란색의 500 쉐이드는 녹색의 500 쉐이드와 지각적 밝기 면에서 동등하게 "중간" 느낌을 주어야 합니다. 기본 헥스 값이 완전히 다르더라도 마찬가지입니다.
  3. WCAG를 인식할 것: 어두운 쉐이드(700~950)는 흰 배경에서 AA 대비를 달성해야 하고, 밝은 쉐이드(50~200)는 검정 배경에서 AA 대비를 달성해야 합니다.

이 철학이 단순한 HSL 명도 공식으로 Tailwind 팔레트를 생성할 수 없는 이유를 설명합니다. 색조마다 고유한 지각적 밝기가 다르기 때문입니다. 노란색은 동일한 HSL 명도 값에서 파란색보다 본질적으로 더 밝습니다. 그래서 각 색상 패밀리에는 개별적인 조정이 필요합니다.

22개 색상 패밀리

Tailwind v3와 v4 모두 22개의 명명된 색상 패밀리를 제공합니다:

패밀리 대표 500 값
Slate #64748B
Gray #6B7280
Zinc #71717A
Neutral #737373
Stone #78716C
Red #EF4444
Orange #F97316
Amber #F59E0B
Yellow #EAB308
Lime #84CC16
Green #22C55E
Emerald #10B981
Teal #14B8A6
Cyan #06B6D4
Sky #0EA5E9
Blue #3B82F6
Indigo #6366F1
Violet #8B5CF6
Purple #A855F7
Fuchsia #D946EF
Pink #EC4899
Rose #F43F5E

다섯 가지 중성 패밀리(slate~stone)는 단순히 동일한 회색의 다른 채도 레벨이 아닙니다. 각각 고유한 색조가 있습니다. slate는 파란-회색으로 기울고, stone은 따뜻한 갈색-회색으로 기울며, neutral이 가장 순수한 무채색입니다. 이를 통해 회색 비계에서 차갑거나, 따뜻하거나, 중성적인 톤이 필요한 환경에서 디자이너가 선택할 수 있습니다.

11단계 쉐이드

각 색상 패밀리에는 11개의 쉐이드가 있습니다:

단계 의도된 용도
50 매우 밝은 색조; 페이지 배경, 섬세한 구분선
100 밝은 색조; 카드 배경, 테이블 줄무늬
200 밝은 중간 톤; 테두리, 비활성 상태
300 중간-밝음; 어두운 배경의 플레이스홀더 텍스트
400 중간 톤; 보조 아이콘, 보조 텍스트
500 "순수" 색조; 주요 브랜드 색상, 배지
600 어두운 중간 톤; 500색 요소의 호버 상태
700 어두움; 밝은 배경의 주요 텍스트
800 매우 어두움; 제목, 강조 텍스트
900 거의 검정; 최대 텍스트 대비
950 가장 어두움; v3.3에서 추가, 더 깊은 그림자 레이어링

950 쉐이드는 나중에 추가되었습니다. 디자이너들이 특히 서피스 색상이 매우 어둡고 레이어링에 더 깊은 쉐이드가 필요한 다크 모드에서 깊은 그림자 효과에 900이 충분히 어둡지 않다는 것을 발견했기 때문입니다.

500 단계는 의도적으로 각 색상의 "정식" 쉐이드입니다. "파란색을 원한다" 또는 "초록색을 원한다"고 말할 때 기대하는 것처럼 보이는 색이며, 다른 모든 단계는 이 기준점을 상대적으로 이해됩니다.

쉐이드 알고리즘이 작동하는 방식

Tailwind의 색상은 직접 큐레이션되었지만, 팀은 지각적 일관성을 유지하기 위해 OKLCH 색 공간을 기반으로 한 프로세스를 사용했습니다. OKLCH(Oklab 명도 채도 색조)는 명도의 동일한 수치 변화가 색조와 관계없이 동등한 지각적 밝기 변화를 생성하도록 설계되었습니다. HSL이나 RGB에서는 색조 변화가 지각적 명도를 극적으로 변화시킵니다.

색상 패밀리에 대한 일반적인 프로세스는 다음과 같습니다:

  1. 500 값 선택: 이 패밀리의 기본 브랜드 색상을 OKLCH 또는 동등한 지각적 공간으로 정의합니다.
  2. 각 단계의 명도 목표 설정: 11단계를 특정 OKLCH 명도 값에 매핑합니다. 예를 들어, 50단계는 OKLCH 명도 0.97을 목표로 하고, 950단계는 0.13을 목표로 합니다.
  3. 채도와 색조 유지: 가능한 한 단계 전반에서 채도(채도)와 색조 각도를 일정하게 유지하고 명도만 조정합니다.
  4. 색조 이동에 대한 수동 조정: 많은 색조는 OKLCH에서 밝아지거나 어두워질 때 원하지 않는 색조 이동을 보입니다. 예를 들어 노란색은 어두워지면 초록빛으로 이동하는 경향이 있습니다. 이런 이동을 수정하기 위한 인간의 조정이 각 단계에 필요합니다.
  5. sRGB 헥스로 변환: 최종 OKLCH 값은 CSS에서 사용하기 위한 헥스 코드로 변환됩니다.

이 프로세스의 결과는 Tailwind 팔레트가 노란색과 파란색을 처리하는 방식을 비교하면 볼 수 있습니다. 파란색 단계는 온도가 약간 변화하고(가장 어두운 파란색은 더 인디고 성격을 띱니다), 노란색 단계는 탁해지는 것을 피하기 위해 어두워질 때 올리브 쪽으로 이동합니다. 이는 어떤 순수 알고리즘도 자동으로 생성할 수 없는 의도적인 지각적 수정입니다.

색상 변환기를 사용하여 OKLCH 공간에서 Tailwind 헥스 값을 검토하고, 스케일 전반에서 명도, 채도, 색조가 어떻게 변하는지 확인할 수 있습니다.

Tailwind 색상 팔레트 커스터마이즈

Tailwind v3 (tailwind.config.js)

Tailwind v3에서는 tailwind.config.js에서 팔레트를 확장하거나 교체합니다:

// tailwind.config.js
module.exports = {
  theme: {
    extend: {
      colors: {
        brand: {
          50:  '#f0f9ff',
          100: '#e0f2fe',
          200: '#bae6fd',
          300: '#7dd3fc',
          400: '#38bdf8',
          500: '#0ea5e9',
          600: '#0284c7',
          700: '#0369a1',
          800: '#075985',
          900: '#0c4a6e',
          950: '#082f49',
        },
      },
    },
  },
}

extend를 사용하면 모든 내장 색상이 유지됩니다. theme.colors를 직접 교체하면 제거됩니다.

Tailwind v4 (CSS 우선 설정)

Tailwind v4는 JavaScript 설정 파일을 없앴습니다. 색상은 이제 메인 CSS 파일에서 CSS 커스텀 프로퍼티로 정의됩니다:

@import "tailwindcss";

@theme {
  --color-brand-50: #f0f9ff;
  --color-brand-100: #e0f2fe;
  --color-brand-200: #bae6fd;
  --color-brand-300: #7dd3fc;
  --color-brand-400: #38bdf8;
  --color-brand-500: #0ea5e9;
  --color-brand-600: #0284c7;
  --color-brand-700: #0369a1;
  --color-brand-800: #075985;
  --color-brand-900: #0c4a6e;
  --color-brand-950: #082f49;
}

이렇게 하면 내장 색상과 정확히 동일하게, 하지만 커스텀 색조로 bg-brand-50부터 bg-brand-950, text-brand-*, border-brand-* 등의 유틸리티 클래스가 생성됩니다.

Tailwind v4에서 변경된 사항

Tailwind v4는 색상 시스템에 몇 가지 중요한 변경 사항을 도입했습니다:

CSS 변수가 진실의 원천

v4에서 모든 내장 색상은 CSS 커스텀 프로퍼티로 노출됩니다. 즉, Tailwind 유틸리티 클래스 없이도 일반 CSS에서 모든 Tailwind 색상에 접근할 수 있습니다:

.custom-element {
  background-color: var(--color-blue-500);
  border-color: var(--color-blue-200);
}

v3에서는 추가 도구나 헥스 값의 수동 복제 없이는 이것이 쉽지 않았습니다.

OKLCH 색상 값

Tailwind v4는 sRGB 헥스 대신 OKLCH로 색상을 표현합니다. 이는 몇 가지 장점이 있습니다:

  • 광역 색영역 지원: P3 또는 Rec. 2020 색영역을 지원하는 디스플레이에서 헥스 코드로 표현 가능한 것보다 더 선명한 색상을 사용할 수 있습니다.
  • 더 나은 보간: 두 Tailwind 색상 사이의 그라디언트가 더 지각적으로 균일한 결과를 만들어냅니다.
  • 예측 가능한 조작: OKLCH에서 명도를 조절하는 것이 HSL에서 조절하는 것보다 더 신뢰할 수 있습니다.

유틸리티 클래스를 사용하는 개발자에게는 대부분 투명합니다. bg-blue-500은 여전히 파란 배경을 만듭니다. 하지만 색상 사이를 보간하는 커스텀 그라디언트나 애니메이션을 만드는 경우에는 중요합니다.

시맨틱 색상 토큰

v4는 또한 색상의 외관이 아닌 역할로 설명하는 시맨틱 색상 토큰에 대한 더 나은 지원을 도입했습니다:

@theme {
  --color-primary: var(--color-blue-600);
  --color-primary-hover: var(--color-blue-700);
  --color-surface: var(--color-slate-50);
  --color-on-surface: var(--color-slate-900);
}

이 패턴은 디자인 시스템의 시맨틱 레이어를 Tailwind의 스케일 레이어에 매핑하여, 컴포넌트 마크업을 변경하지 않고 테마를 전환할 수 있게 합니다.

Tailwind에 맞는 커스텀 스케일 만들기

기본 팔레트에 없는 색상이 필요한 경우 — 브랜드의 특정 주황색이나 맞춤형 초록색 — 두 가지 옵션이 있습니다: 가장 가까운 내장 패밀리를 찾아 조정하거나, 완전히 새로운 스케일을 생성하는 것입니다.

쉐이드 생성기 사용

쉐이드 생성기는 단일 입력 헥스 코드에서 완전한 50~950 스케일을 생성합니다. 브랜드의 기본 색상을 입력하면 도구가:

  1. 헥스를 OKLCH로 변환
  2. 11단계 각각의 명도 목표를 계산
  3. 더 밝은 쉐이드는 채도를 낮추고 어두운 쉐이드는 깊이를 유지하도록 채도를 적절히 조정
  4. Tailwind 설정에 바로 붙여넣을 수 있는 sRGB 헥스 값 출력

예를 들어, 브랜드 색상이 #0F766E (청록-초록색)이라면, 생성기가 다음을 생성할 수 있습니다:

단계 헥스
50 #F0FDFA
100 #CCFBF1
200 #99F6E4
300 #5EEAD4
400 #2DD4BF
500 #14B8A6
600 #0D9488
700 #0F766E
800 #115E59
900 #134E4A
950 #042F2E

이것은 Tailwind의 내장 Teal 스케일과 일치하며, 생성기의 출력이 공식 팔레트의 시각적 특성과 일치함을 보여줍니다.

다크 모드에 Tailwind 색상 사용하기

Tailwind의 쉐이드 시스템은 스케일이 거울상 값을 제공하기 때문에 다크 모드에 잘 맞습니다. 일반적인 관례:

라이트 모드 다크 모드 목적
slate-50 slate-900 페이지 배경
slate-100 slate-800 카드 배경
slate-200 slate-700 테두리
slate-900 slate-100 본문 텍스트
blue-600 blue-400 주요 액션

핵심 인사이트는 색상이 아닌 쉐이드 번호를 반전시키는 것입니다. 라이트 모드에서 slate-100을 사용하는 곳에서 다크 모드에서는 slate-900을 사용합니다. 링크와 버튼 같은 인터랙티브 색상의 경우, 라이트 모드에서는 더 어두운 쉐이드(600)에서 다크 모드에서는 더 밝은 쉐이드(400)로 이동하여 다른 배경에 대한 대비를 유지합니다.

Tailwind의 dark: 변형이 이를 체계적으로 만들어줍니다:

<div class="bg-slate-50 dark:bg-slate-900 text-slate-900 dark:text-slate-100">
  <button class="bg-blue-600 dark:bg-blue-400 text-white dark:text-slate-900">
    Action
  </button>
</div>

일반적인 색상 시스템 실수

두 모드에 동일한 쉐이드 사용

dark: 재정의 없이 bg-blue-600을 적용하는 것은 흔한 실수입니다. 다크 모드에서 어두운 배경에 밝은 파란색 요소는 괜찮아 보이지만, 어두운 배경의 흰 카드는 거슬립니다. 배경 색상에는 항상 라이트와 다크 변형을 모두 정의하세요.

대비를 위해 인접하지 않은 쉐이드 선택

gray-300 배경에 gray-400 텍스트를 사용하면 대비가 부족합니다. 일반적인 규칙: 전경색과 배경색 쉐이드 간에 최소 4단계 차이를 유지하세요(예: slate-100 위의 텍스트는 최소 slate-700이어야 합니다). 대비 검사기를 사용하여 특정 조합이 WCAG AA(4.5:1) 또는 AAA(7:1)를 충족하는지 확인하세요.

너무 많은 색상 패밀리 사용

Tailwind 팔레트에는 22개 패밀리가 있지만, 대부분의 인터페이스는 최대 세 개만 필요합니다: 중성(gray/slate), 주요 브랜드 색상, 그리고 시맨틱 상태(오류는 빨강, 성공은 초록, 경고는 노랑) 하나씩. 네 가지 이상의 서로 다른 색상 패밀리를 선택하면 목적 없이 시각적 복잡성이 생깁니다.

핵심 요약

  • Tailwind CSS는 22개의 색상 패밀리를 탑재하며, 각각 50~950까지 11개의 쉐이드를 포함합니다. 단순한 산술 공식이 아닌 지각적 명도 분석과 인간의 큐레이션을 통해 생성됩니다.
  • 다섯 가지 중성 패밀리(slate, gray, zinc, neutral, stone)는 각각 고유한 색조를 가져, 디자이너에게 따뜻하거나 차갑거나 중성적인 회색 옵션을 제공합니다.
  • 500 단계가 각 색상 패밀리의 정식 "순수" 쉐이드이며, 다른 모든 단계는 이를 기준으로 이해됩니다. 950 단계는 더 깊은 그림자와 다크 서피스 레이어링을 위해 v3.3에서 추가되었습니다.
  • Tailwind v4는 @theme을 사용한 CSS 우선 설정으로 전환하고, 모든 색상을 CSS 커스텀 프로퍼티로 노출하며, 더 나은 지각적 균일성과 광역 색영역 지원을 위해 내부적으로 OKLCH를 사용합니다.
  • 쉐이드 생성기는 OKLCH 기반 명도 목표를 사용하여 입력 헥스 코드에서 완전한 Tailwind 호환 50~950 스케일을 생성합니다.
  • 다크 모드에서는 색조를 반전시키는 것이 아니라 쉐이드 번호를 반전시키세요(50 ↔ 900). 인터랙티브 색상은 다크 배경에 대한 대비를 유지하기 위해 어두운 쉐이드(600)에서 밝은 쉐이드(400)로 이동하세요.

관련 색상

관련 브랜드

관련 도구