Material Design 3 와 디자인 토큰
Material Design 3 와 디자인 토큰
Material Design 은 Google 이 2014 년에 발표한 디자인 시스템입니다. 2021 년 Material 3 (M3) 로 큰 갱신을 거쳤습니다.
1. Material Design 의 역사
| 버전 | 발표 | 사건 |
|---|---|---|
| Material 1 | 2014 (Google I/O) | Matías Duarte 발표. 종이·잉크 메타포. |
| Material 2 | 2018 | 컴포넌트 표준화. Material Theming. |
| Material 3 | 2021 | "Material You". 동적 색상 (HCT 색공간). |
Material 3 의 큰 변화는 두 가지로 정리됩니다.
① 동적 색상 (dynamic color) — 사용자의 배경(Android 12+) 또는 한 색에서 색 팔레트 전체를 자동 생성
② 디자인 토큰의 1급 모델화 — 컴포넌트 속성을 직접 적지 않고 토큰을 가리킴
2. 디자인 토큰
W3C Design Tokens Community Group (DTCG) 이 2021 년부터 표준화 작업을 진행 중입니다. 토큰은 디자인 결정의 이름 있는 작은 값입니다.
{
"color": {
"primary": { "$value": "#6750A4", "$type": "color" }
},
"spacing": {
"sm": { "$value": "8px", "$type": "dimension" },
"md": { "$value": "16px", "$type": "dimension" }
}
}
Style Dictionary (Amazon) 같은 도구가 이 JSON 을 CSS 변수·Swift·Kotlin 으로 변환합니다.
3. M3 의 토큰 카테고리
| 카테고리 | 예시 토큰 |
|---|---|
| Color | md.sys.color.primary · md.sys.color.on-primary · md.sys.color.surface |
| Typography | md.sys.typescale.headline-large · md.sys.typescale.body-medium |
| Shape | md.sys.shape.corner.small · md.sys.shape.corner.large |
| Elevation | md.sys.elevation.level0~`level5` |
| Motion | md.sys.motion.duration.short2 · md.sys.motion.easing.standard |
| State | hover/focus/pressed/dragged 의 layer opacity |
토큰은 세 단계로 계층화됩니다.
- ref (reference) — 원자값.
md.ref.palette.primary40 = #6750A4. - sys (system) — 의미가 붙은 토큰.
md.sys.color.primary = ref.palette.primary40. - comp (component) — 컴포넌트별.
md.comp.button.filled.container.color = sys.color.primary.
이 계층 덕분에 다크 모드 · 동적 색상 · 브랜드 변형이 sys 단계만 갈아끼우면 컴포넌트는 그대로 따라갑니다.
4. HCT 색공간
M3 의 동적 색상은 HCT (Hue · Chroma · Tone) 색공간을 사용합니다. Google 이 CAM16 + L* 을 결합해 만든 색공간으로, 같은 Tone 끼리 비교 시 인지적 명도가 가까워 접근성 (대비비) 계산에 유리합니다.
material-color-utilities (Google) 라이브러리가 다음을 제공합니다.
- 한 색에서 5 개의 톤 팔레트 (primary · secondary · tertiary · neutral · neutral-variant) 생성.
- 각 팔레트의 13 단계 톤 (0 · 10 · 20 · ... · 100).
- 라이트/다크 스킴 자동 매핑.
import { themeFromSourceColor, hexFromArgb } from "@material/material-color-utilities"
const theme = themeFromSourceColor(0xff6750a4)
const primary = hexFromArgb(theme.schemes.light.primary)
5. 모션 토큰
M3 는 모션도 토큰화했습니다.
- Duration — short1
short4 (50200ms) · medium1medium4 (250400ms) · long1long4 (450600ms) · extra-long. - Easing — standard · emphasized · emphasized-decelerate · emphasized-accelerate.
emphasized 는 시작은 빠르고 끝은 부드러운 곡선으로 정의돼 있습니다 (cubic-bezier(0.2, 0.0, 0.0, 1.0) 근처).
6. React 에서 M3 구현하는 길
| 방식 | 라이브러리 | 비고 |
|---|---|---|
| 컴포넌트 라이브러리 | MUI (Material UI) v5/v6 | M2 기반. v6 가 M3 토큰을 점진 도입. 가장 큰 사용처. |
| 웹 컴포넌트 | @material/web |
Google 이 직접 만든 M3 웹 컴포넌트. React 에서 <md-filled-button> 사용. |
| 토큰만 가져옴 | material-color-utilities + 직접 컴포넌트 |
shadcn/Radix/Tailwind 와 결합. |
| Tailwind 통합 | tailwindcss-material-colors 같은 플러그인 |
utility 와 토큰 결합. |
@material/web 은 v1.0 (2024) 이후 신규 기능 개발이 중단되어 유지보수 모드로 알려졌습니다. 지속 가능한 길로는 토큰만 가져와 자체 컴포넌트에 매핑하거나 MUI 의 M3 지원을 따라가는 두 갈래가 자주 거론됩니다.
7. 다른 디자인 시스템들
| 시스템 | 출처 | 특징 |
|---|---|---|
| Material 3 | 안드로이드/웹 표준. | |
| Apple HIG | Apple | iOS/macOS 가이드. |
| Microsoft Fluent 2 | Microsoft | Windows · Office. Fluent UI React. |
| Carbon Design System | IBM | 엔터프라이즈. |
| Atlassian Design System | Atlassian | |
| Polaris | Shopify | |
| Ant Design | Alibaba (2015) | 중국 엔터프라이즈 강세. |
8. Headless + 토큰 모델
현재 React 진영에서 자주 보이는 패턴:
- Radix UI (접근성 헤드리스 컴포넌트) + Tailwind (스타일) + CSS 변수 토큰.
- 컴포넌트는 자체 작성 (또는 shadcn 으로 복사).
- 토큰은 M3 에서 추출한 색을 CSS 변수에 매핑.
이 모델은 디자인 시스템에 종속되지 않고 토큰만 차용한다는 점이 강점으로 거론됩니다.
9. CSS 변수로 M3 토큰 매핑
:root {
--md-primary: oklch(0.50 0.13 290);
--md-on-primary: oklch(1.00 0 0);
--md-surface: oklch(0.99 0.005 90);
--md-on-surface: oklch(0.15 0.01 90);
--md-outline: oklch(0.65 0.02 90);
--md-shape-sm: 4px;
--md-shape-md: 12px;
--md-shape-lg: 16px;
--md-easing-standard: cubic-bezier(0.2, 0, 0, 1);
--md-duration-short2: 100ms;
}
.dark {
--md-primary: oklch(0.78 0.13 290);
--md-on-primary: oklch(0.20 0.05 290);
--md-surface: oklch(0.18 0.01 90);
--md-on-surface: oklch(0.95 0.005 90);
}
10. 동적 색상 생성
import { argbFromHex, themeFromSourceColor, hexFromArgb }
from "@material/material-color-utilities"
const source = argbFromHex("#0061a4")
const theme = themeFromSourceColor(source)
const tokens = {
primary: hexFromArgb(theme.schemes.light.primary),
onPrimary: hexFromArgb(theme.schemes.light.onPrimary),
surface: hexFromArgb(theme.schemes.light.surface),
}
11. 자주 걸리는 자리
M2 와 M3 혼용 — MUI 마이너 버전마다 토큰이 다릅니다. 한 코드베이스 안에서 M2 컴포넌트와 M3 컴포넌트가 섞이면 디자인 일관성이 깨집니다.
동적 색상의 대비비 검증 — HCT 가 톤을 같게 맞춰주지만 모든 조합이 WCAG 4.5:1 을 보장하지는 않습니다. 텍스트·배경 짝은 별도 검증.
토큰 이름 변경 — M3 가 안정화되는 과정에서 토큰 이름이 여러 번 바뀌었습니다. 공식 문서의 현재 이름 기준으로 매핑.
@material/web 의 React 통합 — 웹 컴포넌트라 React 의 props/event 와 살짝 어색합니다. @lit-labs/react 같은 래퍼가 자주 쓰였습니다.
다크 모드 자동 매핑 — Material 의 라이트/다크 톤은 단순 invert 가 아닙니다. ref-palette 를 만들고 sys 매핑 표를 따로 갖습니다.
하고픈 말
Material Design 3 자체를 통째로 들이면 코드베이스가 무거워집니다. 토큰만 가져와 자체 컴포넌트 + Tailwind 위에 얹는 흐름이 가벼우면서도 일관성을 유지하는 길입니다. 동적 색상은 사용자 자유도가 큰 자리에 들이고, 일반 앱은 정적 토큰으로 시작합니다.
Next
- forms-zod
- bundlers
Material 3 · Material Components GitHub · @material/web · material-color-utilities · W3C Design Tokens · Style Dictionary · MUI · Radix UI 를 참고합니다.