視覺層級與 Design Tokens
如果每個按鈕都直接寫 #2563eb,第一版也許能運作,但之後很快會遇到三個問題:品牌色無法集中修改、深色模式到處出現例外、AI 每次生成的間距和狀態不一致。
Design Token(設計 Token) 是把設計決策命名並集中管理的方式。本課會從原始值開始,建立可以用在 CSS、Tailwind 或元件系統中的語意層。
三層 Token 模型
:root {
/* 1. Primitive:原始值,只在 Token 檔案中使用 */
--blue-600: 37 99 235;
--slate-900: 15 23 42;
--slate-500: 100 116 139;
--space-4: 1rem;
/* 2. Semantic:依用途命名 */
--color-action: var(--blue-600);
--color-heading: var(--slate-900);
--color-muted: var(--slate-500);
--space-section: calc(var(--space-4) * 3);
/* 3. Component:元件的局部決策 */
--button-primary-bg: var(--color-action);
--card-title-color: var(--color-heading);
}
元件應讀取 --button-primary-bg 或 --color-action,而不是直接讀取 --blue-600。這樣換主題時,修改映射就足夠。
建立色彩角色
先列出頁面需要的角色,再填入顏色:
:root {
--surface-page: 248 250 252;
--surface-card: 255 255 255;
--text-primary: 15 23 42;
--text-secondary: 71 85 105;
--border-default: 226 232 240;
--focus-ring: 37 99 235;
--status-success: 22 163 74;
--status-danger: 220 38 38;
}
body {
background: rgb(var(--surface-page));
color: rgb(var(--text-primary));
}
--status-danger 的用途是表達錯誤,不代表它可以直接當作按鈕背景。每個角色都應附上使用情境和禁用情境。
間距與字級也要有尺度
不要在頁面中出現 13px、17px、23px 等無法解釋的數字。先建立有限尺度:
:root {
--space-1: 0.25rem;
--space-2: 0.5rem;
--space-3: 0.75rem;
--space-4: 1rem;
--space-6: 1.5rem;
--space-8: 2rem;
}
小尺度用於元件內部,大尺度用於區段之間。尺度不用很大,重點是讓相同關係使用相同值。
加入深色模式
語意 Token 的好處會在換主題時出現:
[data-theme='dark'] {
--surface-page: 15 23 42;
--surface-card: 30 41 59;
--text-primary: 241 245 249;
--text-secondary: 148 163 184;
--border-default: 51 65 85;
--focus-ring: 129 140 248;
}
不要把亮色的灰階反向套用到深色模式。深色主題要重新檢查文字對比、邊框、圖表和 focus ring。
常見錯誤
- Token 名稱描述顏色而非用途:
--light-blue無法告訴使用者能否用在錯誤狀態。 - 所有元件都直接讀 raw token:換主題時會留下大量例外。
- 只建立成功狀態:
disabled、error和focus常常才是最容易失去對比的地方。
課後練習
選一個既有頁面,找出所有直接寫死的色彩和間距。把它們分成 raw、semantic、component 三層,然後切換一個深色主題,記錄哪些元件需要新增角色。
下一課會把 Token 套用到按鈕、輸入框和卡片的互動狀態。