0-4. 디자인 토큰(Design Token)

wooseok·2026년 3월 8일

머먹지

목록 보기
4/4
post-thumbnail

디자인 시스템 배포를 위한 파일 구조가 어느정도 잡혀서 다음으로 넘어가기로 했다.💨
크게 토큰과 아이콘, ui로 나눠서 진행할 예정
디자이너분들 앞에서 모르는데 아는 척하지 않기 위해 미리 개념 정도는 잡고 가보려고 한다..🤓


🤔 디자인 토큰이란?

나는 디자인 토큰이 "디자인에 사용하는 속성값을 변수에 저장한 것"이라고 이해했다.

예를 들어 #ABC123이라는 색상이 있고 이를 그대로 다양한 요소에 적용을 해두고 개발을 하다가 다양한 이유로 이 색상을 변경하려면?
➡️ 그 요소를 포함하고 있는 모든 곳에 가서 하나하나 수정해야하는 대참사가......☠️

💡 이런 값들을 변수에 담아 토큰화해두면 한 곳에서만 수정하면 된다!! 🙌

또한 개발자와 디자이너 사이에 소통에도 많은 도움이 될 것 같다..!
ex) 👨‍🎨: primary 색상 변경해주세요~ // 🧑‍💻: 그게 무슨 색인데요?
⬇️
👨‍🎨: color-primary 색상이 변경되었습니다. 업데이트해주세요 // 🧑‍💻: 넵! 토큰 업데이트 하겠습니다!


🏗️ 토큰의 구조

토큰은 보통 3단계로 이루어져 있다고 한다.
1단계: Primitive Token (원시 토큰)

  • 하드코딩된 속성값에 이름을 붙여준 토큰
  • ❌ 이름에 의미를 담으면 안됨!! ❌ (이름 + 의미 = 시맨틱 토큰)
{
  "color-blue-500": "#4F46E5",
  "color-gray-100": "#F3F4F6",
  "space-4": "16px"
}

2단계: Semantic Token (의미 토큰)

  • Primitive token에 의미를 부여한 코드
{
  "color-primary": "{color-blue-500}",
  "color-background": "{color-gray-100}",
  "spacing-button-padding": "{space-4}"
}

3단계: Component Token (컴포넌트 토큰)

  • 특정 컴포넌트에 귀속된 토큰
{
  "button-bg-color": "{color-primary}",
  "button-text-color": "{color-white}",
  "button-padding": "{spacing-button-padding}"
}

❓ 시맨틱 토큰 없이 원시 토큰 단계에서 붙인 속성값들의 이름을 바로 컴포넌트 토큰에 넣으면 안되나?
✅ 원시 토큰에는 의미가 부여되지 않았기 때문에 컴포넌트 토큰에 원시 토큰의 이름을 그대로 쓴다면 하드코딩된 값을 쓰는 것과 별반 다르지 않다.
여전히 컴포넌트 안의 속성값이 다르면 일일이 수정해줘야 한다는 뜻이다.
(그냥 속성값을 한 번 더 쓴 사람이 되고 싶다면 추천..)


🏁 토큰이 커버하는 범위

단순히 색상이나 간격 정도만 있는 줄 알았는데 생각보다 범위가 넓어서 멈칫했다.

📌 Color / Border / Shadow / Size

📌 Typography

  • font-size, font-weight, line-height 등 글자와 관련된 모든 것이 포함된다.

📌 Spacing

  • 보통 4px 배수로 설계해서 디자이너 그리드 시스템이랑 통일시킨다는데 이 부분은 물어봐야겠다..!

📌 Motion

  • 애니메이션도 여기에 포함되는지 처음 알았다. 다양한 컴포넌트에 공통적으로 적용할 애니메이션들을 모아두면 유용하게 사용할 수 있을 것 같았다.

📌 Z-index

  • 이 부분도 처음 알게 된 부분인데, 레이어 순서를 토큰으로 관리하면 레이어 충돌 문제를 사전에 예방할 수 있어서 좋아보인다.

💼 네이밍 규칙 (타 프로젝트 예시)

다른 서비스/프로젝트의 디자인 시스템들을 염탐하려고 보니 전부 다 공개를 해놓지는 않았더라.
우리 프로젝트도 어디까지 공개할지 정해봐도 괜찮을 것 같다.

  • Radix UI : Primitive와 Semantic은 공개해뒀지만 Component는 비공개
  • Shopify Polaris : Primitive를 숨기고 Semantic, Component는 공개
  • Chakra UI : JS 객체 형태로 관리하는 특징. CSS 변수가 아닌 JS Theme 객체에서 토큰을 정의. 이렇게도 디자인 토큰을 저장해놓을 수 있다는 것을 배웠다.
// Chakra UI 방식
Primitive   →  colors.blue[500]: "#4299E1"
Semantic    →  colors.brand.primary: "blue.500"
Component   →  theme.components.Button.baseStyle
  • Github Primer : 네이밍 규칙 3단계 구조를 제일 두드러지게 볼 수 있었던 것 같다. 대신 이름이 좀 길어지는 것 같음...
// Github Primer 방식
Primitive   →  --color-scale-blue-5: #0969da
Semantic    →  --color-accent-fg: var(--color-scale-blue-5)
Component   →  --color-btn-primary-bg: var(--color-accent-fg)
  • atlassian design system : 접두사로 네임스페이스를 구분하고, 상태까지 토큰 이름에 포함시켰음!
    atlassian design system 전체 토큰

    🌗 다크모드 대응 방식

  • Radix UI : 클래스 기반

    • class="dark"를 루트에 붙이는 방식. Semantic 토큰 값만 교체해서 다크모드 구현
  • Shopify Polaris : 미디어 쿼리 기반

    • 시스템 설정을 자동으로 따라가는 방식. 수동 토글 없이 OS 설정에 연동됨.
  • Chakra UI

    • React Context로 모드를 관리하고, JS 레벨에서 속성값을 교체. CSS 변수 방식보다 JS 의존도가 높음
  • Github Primer

    • data-color-mode 속성을 HTML에 붙이는 방식.
[data-color-mode="light"] { --color-canvas-default: #ffffff; }
[data-color-mode="dark"]  { --color-canvas-default: #0d1117; }

👨‍🎨 그렇다면 우리 프로젝트에서는?!

🥸☝️ 팀의 상황과 프로젝트 규모가 전부 다르기에 어쨌든 우리 팀의 맞는 설정을 잘 논의하는 게 중요하다는 것을 깨달았고 다 같이 얘기해 보면 좋을 주제를 몇 가지 생각해 보았다.

1. 네이밍 컨벤션

  • 접두사를 쓸지말지? ( --mm-color-primary vs --color-primary )
  • 숫자 스케일 방식 ( blue-500 vs blue-5 vs blue-md )
  • 상태를 토큰 이름에 포함할지? ( --color-button-hovered )

2. 공개 범위 설정

  • 외부에 전체를 공개할지? ( Primitive나 Component 토큰은 공개 안할 수도 있고~ )
  • 토큰을 3단계로 만들건지, 아니면 시맨틱에서 멈출건지?

3. Figma

  • Figma Variables로 토큰 관리를 할지?

4. 다크모드 지원 여부와 방식

  • 다크모드를 처음부터 염두해서 작업을 할지?
  • 만약 하게 된다면 어떤 방식으로 할지? (클래스 기반? 미디어 쿼리? ···)

5. 토큰으로 어디까지 포함할건지?

  • 애니메이션이나 z-index까지 토큰으로 관리할건지?

🔗 참고자료
KRDS 디자인 토큰
'디자인시스템'과 '디자인 토큰'에 관한 가장 쉬운 개념 정리!(Design System & Design Token)
Figma 디자인 시스템에서의 디자인 토큰 vs 베리어블(Variables) 완전 정리

0개의 댓글