통합 요약노트
Ch.14 디자인 토큰과 시스템
이론을 시스템으로 — 토큰, 원자 디자인, 컴포넌트 설계
이 챕터의 내용
디자인 토큰의 개념
답은 값(value)이 아닌 이름(token)으로 소통하는 것 — 디자인 토큰은 디자인과 코드를 연결하는 단일 진실 공급원(Single Source of Truth)입니다.
값에 이름을 붙이면 시스템이 됩니다
디자인 토큰(Design Token)이란 색상, 간격, 폰트 크기 등 시각적 속성을 이름-값 쌍으로 저장한 것입니다. CSS 변수, JSON, 또는 코드 상수로 관리되며, 디자인 도구와 코드가 동일한 값을 참조합니다.
디자인 토큰 = 시각적 속성의 이름-값 쌍 → 디자인과 코드의 단일 진실 공급원
- 디자인 토큰 = 시각적 속성의 이름-값 쌍 (Single Source of Truth)
- Primitive 토큰: 원시값 정의 (blue-500 = #3B82F6)
- Semantic 토큰: 역할 부여 (color.primary = blue-500)
- 토큰 기반 시스템은 일관성·테마 전환·소통·확장성 모두 우월
- 색상 3계층: Primitive → Semantic → Component
- 간격은 4px 배수 체계(4, 8, 16, 32…)가 표준
원자 디자인과 컴포넌트
브래드 프로스트의 Atomic Design — 화학의 원자·분자 개념을 UI에 적용하여, 작은 단위에서 큰 화면까지 조립하듯 설계하는 방법론입니다.
UI를 원자부터 조립합니다
Atomic Design은 브래드 프로스트(Brad Frost)가 2013년에 제안한 UI 설계 방법론입니다. 화학에서 원자가 분자를 이루고 분자가 유기체를 이루듯, UI도 가장 작은 단위에서 큰 단위로 합성(compose)해 나갑니다.
Atomic Design 5계층
- Atomic Design 5계층: Atoms → Molecules → Organisms → Templates → Pages
- 각 계층은 아래 계층의 조합으로만 구성된다 (합성의 원칙)
- Variant: 동일 컴포넌트의 시각적·기능적 변형 (Primary, Secondary, Ghost…)
- 좋은 컴포넌트 API: 최소 Props, 단일 책임, 토큰 기반, 자유로운 합성
- Props 10개 이상 → 컴포넌트 분리 신호
이론의 토큰화
이론을 토큰과 제약 조건으로 변환하면, 올바른 선택이 기본값이 됩니다 — 지식이 시스템이 되는 순간, 실수는 구조적으로 불가능해집니다.
8px 그리드가 토큰이 되면
8px 그리드 시스템은 모든 간격과 크기를 8의 배수로 정의하는 규칙입니다. 이것을 토큰화하면 `spacing.xs = 4px`, `spacing.sm = 8px`, `spacing.md = 16px`, `spacing.lg = 32px`이 됩니다. 개발자는 '16px'이 아니라 `spacing.md`를 쓰므로, 8px 그리드를 벗어날 수가 없습니다.
모듈러 스케일(Modular Scale)은 특정 비율(주로 1.25 또는 1.333)을 기준으로 폰트 크기를 단계적으로 정의하는 방법입니다. 토큰화하면 `fontSize.sm = 14px`, `fontSize.md = 16px`, `fontSize.lg = 20px`, `fontSize.xl = 25px`이 됩니다.
- 8px 그리드 → spacing 토큰 (xs:4, sm:8, md:16, lg:24, xl:32)
- 모듈러 스케일 → fontSize 토큰 (비율 1.25로 조화로운 크기 체계)
- 60:30:10 법칙 → color.surface(60%) + color.secondary(30%) + color.accent(10%)
- Fitts's Law → touchTarget.min: 44px (터치 영역 최소 크기)
- Miller's Law → maxNavItems: 7 (인지 부하 한계)
- WCAG 2.1 → contrast: 4.5:1 (접근성 명암비)
- 이론이 시스템이 되면 = 실수가 구조적으로 불가능해진다
핵심 용어 모음
blue-500 → color.primary
브랜드 주 색상. 버튼, 링크, 활성 상태에 사용
red-500 → color.error
오류 메시지, 유효성 검사 실패 표시
green-500 → color.success
성공 알림, 완료 상태 표시
gray-100 → color.surface
카드, 패널 등 배경 표면 색상
4px → spacing.xs
아이콘과 텍스트 사이 최소 간격
8px → spacing.sm
인접 요소 간 기본 간격
16px → spacing.md
카드 내부 패딩, 섹션 간 간격
32px → spacing.lg
섹션 구분, 레이아웃 주요 간격
variant
primary | secondary | ghost | danger — 시각적 스타일 전환
size
sm | md | lg — 크기 조절 (토큰 기반 간격·폰트 적용)
disabled
true | false — 비활성 상태 (색상 토큰 자동 전환)
icon
선택적 아이콘 위치 (left | right) — Molecule로의 확장
비교 정리
| 항목 | 토큰 기반 시스템 | 하드코딩 값 |
|---|---|---|
| 일관성 | color.primary 하나만 변경하면 전체 앱이 동기화 | 200개 파일에서 #3B82F6을 일일이 찾아 교체 |
| 테마 전환 | Semantic 토큰 매핑만 교체 → 다크 모드 즉시 적용 | 모든 컴포넌트에 조건문 추가 필요 |
| 소통 | 디자이너: 'primary 색상 변경' → 개발자: 토큰 값만 수정 | 디자이너: '이 파란색 좀 바꿔주세요' → 어떤 파란색? |
| 확장성 | 새 플랫폼(iOS, Android, Web) 추가 시 토큰 변환만 필요 | 플랫폼마다 값을 수동 복사·관리 |
| 항목 | 잘 설계된 컴포넌트 | 잘못 설계된 컴포넌트 |
|---|---|---|
| 책임 | 하나의 역할만 담당 (버튼은 클릭 동작만) | 여러 역할을 한 컴포넌트에 혼합 (버튼+폼+검증) |
| Props | 3~5개의 명확한 Props (variant, size, onClick) | 15개 이상의 Props, 용도 불분명한 플래그 다수 |
| 토큰 사용 | spacing.md, color.primary 등 토큰만 참조 | padding: 16px, color: #3B82F6 하드코딩 |
| 합성 | 다른 컴포넌트와 자유롭게 조합 가능 | 특정 부모 컴포넌트에서만 작동 (강한 결합) |
| 항목 | 시스템으로 구현 | 지식으로만 보유 |
|---|---|---|
| 8px 그리드 | spacing 토큰만 사용 가능 → 13px, 17px은 시스템에 없음 | '8의 배수로 하자'고 약속했지만 padding: 15px이 등장 |
| 명암비 | color.text + color.surface 조합이 4.5:1 미만이면 린트 에러 | WCAG를 알지만, 시간에 쫓겨 검사를 건너뜀 |
| 터치 영역 | touchTarget.min = 44px → 컴포넌트 최소 크기가 강제됨 | Fitts 법칙을 배웠지만 32px 아이콘 버튼이 배포됨 |
| 결과 | 올바른 선택이 기본값 → 실수가 구조적으로 불가능 | 올바른 선택이 의지에 의존 → 실수가 확률적으로 발생 |
퀴즈와 인터랙션으로 더 깊이 학습하세요
play_circle인터랙티브 코스 시작하기