디자인 토큰

Design token

색·간격·폰트 같은 디자인 결정을 이름 붙인 하나의 값으로 저장해, 그 값을 쓰는 모든 컴포넌트가 한 번에 바뀌게 하는 최소 단위.

다른 이름: TokensCSS custom property (design)
···
html
<div class="stage">
  <div class="src">
    <code id="name">color.accent</code>
    <div class="val" id="val"></div>
  </div>
  <svg class="wires" viewBox="0 0 100 60" preserveAspectRatio="none">
    <path d="M10 30 C 30 30, 30 8, 55 8" />
    <path d="M10 30 C 30 30, 30 30, 55 30" />
    <path d="M10 30 C 30 30, 30 52, 55 52" />
  </svg>
  <div class="uses">
    <button class="u btn">Button</button>
    <div class="u tag">Tag</div>
    <div class="u ring"></div>
  </div>
</div>
css
.stage{width:94%;height:86%;display:grid;grid-template-columns:1fr 60px 1fr;align-items:center;gap:0}
.src{display:flex;flex-direction:column;align-items:flex-start;gap:6px;padding:10px;border:1px solid var(--line);border-radius:10px;background:var(--surface)}
.src code{font:700 11px/1 monospace;color:var(--muted)}
.val{width:100%;height:26px;border-radius:6px;background:var(--accent);transition:background .5s}
.wires{width:100%;height:100%}
.wires path{fill:none;stroke:var(--line);stroke-width:1.4}
.uses{display:flex;flex-direction:column;gap:14px}
.u{border-radius:8px;height:26px;display:flex;align-items:center;justify-content:center;font:600 11px/1 sans-serif}
.btn{background:var(--accent);color:#fff;transition:background .5s}
.tag{border:1.5px solid var(--accent);color:var(--accent);transition:border-color .5s,color .5s}
.ring{width:26px;height:26px;border-radius:50%;border:4px solid var(--accent);align-self:center;justify-self:center;transition:border-color .5s}
js
const colors = ['#5b5bf7', '#f25c8a', '#18c29c', '#e08a2b'];
const val = document.getElementById('val');
const els = document.querySelectorAll('.btn,.tag,.ring');
let i = 0;
function apply() {
  const c = colors[i % colors.length];
  val.style.background = c;
  els.forEach((n) => {
    n.style.background = n.classList.contains('btn') ? c : '';
    n.style.borderColor = c;
    n.style.color = n.classList.contains('btn') ? '#fff' : c;
  });
  i++;
}
apply();
setInterval(apply, 1600);

토큰은 "#5B5BF7" 같은 색상 값 자체가 아니라 그 값에 붙인 이름, 예를 들어 `color.accent.default`입니다. 컴포넌트는 값이 아니라 이름을 참조하기 때문에, 토큰의 값 하나만 바꾸면 그 이름을 쓰는 버튼·링크·칩·아바타가 전부 동시에 바뀝니다.

토큰에는 계층이 있습니다. 기본(primitive) 토큰은 `blue-500` 같은 원시 값이고, 의미(semantic) 토큰은 `color.accent`처럼 "무엇에 쓰는가"를 담아 기본 토큰을 가리킵니다. 컴포넌트는 항상 의미 토큰을 참조해야, 나중에 브랜드 컬러가 바뀌어도 컴포넌트 코드는 그대로 둔 채 의미 토큰이 가리키는 기본 토큰만 바꾸면 됩니다.

라이트/다크 모드, 브랜드별 테마도 결국 같은 의미 토큰 이름에 다른 값 집합을 꽂아 넣는 것입니다. W3C Design Tokens Community Group이 도구 간 호환을 위한 공통 JSON 포맷을 정의하고 있습니다.

언제 쓰나

색상·간격을 코드 곳곳에 하드코딩된 값으로 흩어놓지 않고, 다크 모드·리브랜딩·멀티 브랜드를 한 곳에서 바꾸고 싶을 때 도입합니다.