Theme / v2.15.0

UI UX Pro Max

把模糊需求變成可實作、可驗收的介面

基礎觀念

視覺層級與 Design Tokens

從原始色票、字級和間距建立語意化 Design Tokens,讓 AI 產生的元件保持一致,也能支援深色模式。

視覺層級與 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 的用途是表達錯誤,不代表它可以直接當作按鈕背景。每個角色都應附上使用情境和禁用情境。

間距與字級也要有尺度

不要在頁面中出現 13px17px23px 等無法解釋的數字。先建立有限尺度:

: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:換主題時會留下大量例外。
  • 只建立成功狀態disablederrorfocus 常常才是最容易失去對比的地方。

課後練習

選一個既有頁面,找出所有直接寫死的色彩和間距。把它們分成 raw、semantic、component 三層,然後切換一個深色主題,記錄哪些元件需要新增角色。

下一課會把 Token 套用到按鈕、輸入框和卡片的互動狀態。