Guide / 11 min

軟體工程師的設計原則:完整指南

掌握視覺設計基礎以構建更好的介面。格式塔心理學、排版、色彩理論、間距系統、動畫原則,以及Dieter Rams等設計大師的教訓。包含16個優秀產品的案例研究。


title: “軟體工程師設計原則:完整指南” description: “掌握視覺設計基礎,打造更優秀的介面。Gestalt 心理學、字型排版、色彩理論、間距系統、動畫原則,以及來自 Dieter Rams 等設計大師的啟示。包含 16 款傑出產品的案例研究。” date: 2026-01-14 updated: 2026-01-17T13:30:00 author: Blake Crosley category: Design & Development tags: [Design, UI, UX, Typography, Color Theory, Gestalt, Animation, CSS, SwiftUI] url_slugs: - design-principles-software-engineers-complete-guide-2026 - visual-design-fundamentals-developers


軟體工程師的設計原則:完整指南

2026 年 1 月 17 日更新

2026 年 1 月更新: 本指南整合了經典設計原則與現代網頁及 iOS 開發的實作模式。內容涵蓋 Gestalt 心理學、字型排版系統、色彩理論、視覺層次、間距與動畫——以及 Dieter Rams 的設計哲學。請參閱設計研究深入了解 16 款傑出產品。

多年來,我在開發軟體的同時持續研究設計,從 Dieter Rams 等大師身上汲取原則,並深入分析 Linear、Stripe 和 Raycast 等產品的介面。本指南濃縮了這些理解,成為我當初開始關注軟體外觀與體驗時,希望能擁有的完整參考資料。

設計不是裝飾,而是溝通。每一個像素都在傳達功能、層次與意義。業餘軟體與專業軟體之間的差別,在於理解這些原則並一致地應用它們。

本指南假設你已經會寫程式。它教你如何「看」——理解為什麼有些介面感覺順暢自然,而有些卻顯得雜亂無章,更重要的是,教你如何打造前者。


目錄

第一部分:基礎

  1. Gestalt 心理學
  2. 字型排版
  3. 色彩理論
  4. 視覺層次
  5. 間距與節奏
  6. 動畫原則

第二部分:設計哲學

  1. Dieter Rams:十大原則

第三部分:實作

  1. 2025 網頁設計模式
  2. 設計代碼系統
  3. 正確實作深色模式
  4. Figma 匯出工作流程

第四部分:參考資料

  1. 快速參考表
  2. 設計檢查清單
  3. 設計研究

Gestalt 心理學

「整體不同於部分的總和。」— Kurt Koffka

Gestalt 心理學於 1920 年代在德國發展,解釋人類如何感知視覺資訊。大腦不會看到個別的像素——它會將元素組織成有意義的模式。掌握這些原則,就能控制使用者如何感知你的介面。

接近性

相近的元素會被視為一個群組。

這是 UI 設計中最強大的 Gestalt 原則。空間比任何其他視覺屬性都更能傳達關聯性。

錯誤(等距 = 無群組):
┌─────────────────┐
│ Label           │
│                 │
│ Input Field     │
│                 │
│ Label           │
│                 │
│ Input Field     │
└─────────────────┘

正確(不等距 = 清楚的群組):
┌─────────────────┐
│ Label           │
│ Input Field     │ ← 緊密(4px)- 相關
│                 │
│                 │ ← 寬鬆(24px)- 分隔群組
│ Label           │
│ Input Field     │ ← 緊密(4px)- 相關
└─────────────────┘

CSS 實作:

.form-group {
  margin-bottom: 24px;  /* Between groups: wide */
}

.form-group label {
  margin-bottom: 4px;   /* Label to input: tight */
  display: block;
}

SwiftUI 實作:

VStack(alignment: .leading, spacing: 4) {  // Tight within group
    Text("Email")
        .font(.caption)
        .foregroundStyle(.secondary)
    TextField("[email protected]", text: $email)
        .textFieldStyle(.roundedBorder)
}
.padding(.bottom, 24)  // Wide between groups

相似性

具有相同視覺特徵的元素會顯得相關。

當元素看起來相同時,使用者會假設它們的功能也相同。這就是為什麼設計系統會使用一致的按鈕樣式、卡片處理方式和字型排版。

導覽範例:
┌───────────────────────────────────┐
│ [Dashboard] [Projects] [Settings] │  ← 相同樣式 = 相同功能
│                                   │
│ ┌─────┐  ┌─────┐  ┌─────┐        │
│ │Card │  │Card │  │Card │         │  ← 相同樣式 = 相同內容類型
│ └─────┘  └─────┘  └─────┘        │
│                                   │
│ [+ New Project]                   │  ← 不同樣式 = 不同功能
└───────────────────────────────────┘

圖形-背景

內容應該與背景清楚分離。

大腦需要區分「圖形」(聚焦對象)與「背景」(底色)。不良的圖形-背景關係會造成視覺混淆。

技巧: - 對比(淺色圖形配深色背景,或反之) - 陰影(讓圖形浮於背景之上) - 邊框(界定圖形邊緣) - 模糊(模糊背景,銳化圖形)

/* Strong figure-ground relationship */
.card {
  background: var(--color-surface);     /* Figure */
  border-radius: 12px;
  box-shadow: 0 1px 3px rgba(0,0,0,0.1);  /* Elevation */
}

.modal-overlay {
  background: rgba(0, 0, 0, 0.5);  /* Dim ground */
  backdrop-filter: blur(4px);      /* Blur ground */
}

共同區域

在邊界內的元素會被視為群組。

將元素包圍在視覺容器中(卡片、方框、有邊框的區域)表示它們屬於同一群組。

連續性

眼睛會跟隨路徑、線條和曲線。

利用對齊和視覺流動來引導注意力穿越你的介面。

對齊中的連續性:
┌────────────────────────────────┐
│ Logo    [Nav]  [Nav]  [Nav]   │  ← 沿水平軸對齊
├────────────────────────────────┤
│                                │
│ Headline                       │
│ ─────────────────────────────  │  ← 眼睛跟隨左邊緣
│ Paragraph text continues       │
│ along the same left edge       │
│                                │
│ [Primary Action]               │  ← 仍在左邊緣
└────────────────────────────────┘

閉合性

大腦會補完不完整的形狀。

使用者不需要看到每個像素——他們會在腦中補完熟悉的形狀。這讓設計可以更加簡約優雅。

/* Horizontal scroll with partial card (closure) */
.card-carousel {
  display: flex;
  gap: 16px;
  overflow-x: auto;
  padding-right: 48px;  /* Show partial card = scroll hint */
}

.card-carousel .card {
  flex: 0 0 280px;  /* Fixed width, partial visible */
}

Gestalt 快速參考

原則 規則 主要用途
接近性 相關 = 接近,無關 = 遠離 表單欄位、內容區塊
相似性 外觀相同 = 功能相同 按鈕、卡片、導覽
圖形-背景 清楚分離層次 卡片、對話框、覆蓋層
共同區域 邊界將內容群組化 設定區塊、使用者卡片
連續性 跟隨線條和對齊 時間軸、閱讀流動
閉合性 大腦補完形狀 圖示、捲動提示、骨架屏

字型排版

「字型排版是賦予人類語言持久視覺形式的工藝。」— Robert Bringhurst

字型排版是介面設計的基礎。文字傳達功能、層次和品牌。不良的字型排版讓介面更難使用;優秀的字型排版是隱形的——它就是能運作。

字級

一致的字級創造視覺和諧。使用數學比例。

1.25 倍率(建議用於 UI):

:root {
  /* Base: 16px (1rem) */
  --text-xs: 0.64rem;    /* 10.24px - use sparingly */
  --text-sm: 0.8rem;     /* 12.8px - captions, labels */
  --text-base: 1rem;     /* 16px - body text */
  --text-lg: 1.25rem;    /* 20px - lead text */
  --text-xl: 1.563rem;   /* 25px - h4 */
  --text-2xl: 1.953rem;  /* 31.25px - h3 */
  --text-3xl: 2.441rem;  /* 39px - h2 */
  --text-4xl: 3.052rem;  /* 48.8px - h1 */
}

行高(Leading)

行高大幅影響可讀性。不同的內容需要不同的行高。

內容類型 行高 原因
標題 1.1 - 1.2 緊密、粗體、簡短
UI 文字 1.3 - 1.4 標籤、按鈕
內文 1.5 - 1.7 可讀的段落
長篇內容 1.7 - 2.0 文章、文件

行寬(Measure)

最佳行寬可防止眼睛疲勞並提升閱讀理解力。

  • 最佳: 每行 45-75 個字元
  • 目標: 50-65 個字元
  • 絕對上限: 85 個字元
p {
  max-width: 65ch;  /* ch unit = width of '0' character */
}

.article-body {
  max-width: 70ch;
  margin: 0 auto;
}

字型選擇

優先使用系統字型。 它們載入即時、符合平台風格,且針對螢幕最佳化。

:root {
  --font-sans: system-ui, -apple-system, BlinkMacSystemFont,
               'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;

  --font-mono: ui-monospace, 'SF Mono', 'Cascadia Code',
               'JetBrains Mono', Consolas, monospace;
}

在以下情況使用自訂字型: - 品牌區隔(行銷網站) - 編輯/出版風格 - 系統字型無法達成的特定設計意圖

字重建立層次

使用字重來建立層次,不只是字級。

h1 { font-weight: 700; }  /* Bold */
h2 { font-weight: 600; }  /* Semibold */
h3 { font-weight: 600; }  /* Semibold */
.lead { font-weight: 500; }  /* Medium */
p { font-weight: 400; }   /* Regular */
.meta { font-weight: 400; color: var(--text-muted); }

字型排版快速參考

屬性 內文 標題 UI 標籤
字級 16-18px 24-48px 12-14px
字重 400 600-700 500
行高 1.5-1.7 1.1-1.2 1.3-1.4
行寬 45-75ch 不適用 不適用
對齊 靠左 置中可 靠左

色彩理論

「色彩是一種直接影響靈魂的力量。」— Wassily Kandinsky

色彩比文字傳達得更快。它建立情緒、引導注意力、傳遞意義,並建立品牌識別度。

60-30-10 法則

這是創造平衡介面最可靠的色彩分配方式。

┌──────────────────────────────────────────┐
│░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│ 60% - 主色(背景)
│░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
│░░░░░▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓░░░░░░░░│ 30% - 輔助色(卡片、區塊)
│░░░░░▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓░░░░░░░░│
│░░░░░▓▓▓▓▓▓▓▓▓▓▓▓██████▓▓▓▓▓▓▓▓▓▓░░░░░░░░│ 10% - 強調色(按鈕、連結)
└──────────────────────────────────────────┘

建立色彩調色盤

每個介面都需要這些語意色彩:

:root {
  /* Brand */
  --color-primary: hsl(220, 80%, 50%);
  --color-primary-hover: hsl(220, 80%, 45%);

  /* Semantic */
  --color-success: hsl(142, 76%, 36%);  /* Green - positive */
  --color-warning: hsl(38, 92%, 50%);   /* Amber - caution */
  --color-error: hsl(0, 84%, 60%);      /* Red - danger */

  /* Neutrals */
  --color-background: hsl(0, 0%, 100%);
  --color-surface: hsl(220, 14%, 96%);
  --color-border: hsl(220, 13%, 91%);

  /* Text */
  --color-text: hsl(220, 13%, 13%);
  --color-text-secondary: hsl(220, 9%, 46%);
  --color-text-muted: hsl(220, 9%, 64%);
}

色彩心理學

色彩 心理效果 UI 應用
藍色 信任、穩定、平靜 金融、科技、企業
綠色 成長、自然、成功 健康、環保、正向狀態
紅色 能量、緊迫、危險 警示、促銷、錯誤
橘色 溫暖、熱情 CTA、活潑品牌
黃色 樂觀、警示 警告、強調
紫色 奢華、創意 高端產品

無障礙對比度

等級 一般文字 大型文字 UI 元件
AA 4.5:1 3:1 3:1
AAA 7:1 4.5:1 N/A

工具: WebAIM Contrast Checker、Chrome DevTools 色彩選擇器


視覺層級

「設計是品牌的無聲大使。」— Paul Rand

視覺層級控制使用者首先、其次、再其次看到什麼。沒有清晰的層級,使用者必須費力尋找資訊。有了層級,介面讓人感覺毫不費力。

層級的六大工具

1. 大小 — 較大的元素首先吸引注意力

.hero-title { font-size: 3rem; }      /* Dominant */
.section-title { font-size: 1.5rem; } /* Secondary */
.body-text { font-size: 1rem; }       /* Baseline */

2. 字重 — 粗體突出,細體後退

h1 { font-weight: 700; }
.lead { font-weight: 500; }
p { font-weight: 400; }

3. 色彩與對比 — 高對比 = 吸引注意力

.title { color: var(--color-text); }  /* Near black */
.meta { color: var(--color-text-muted); }  /* Gray */

4. 位置 — 關鍵位置很重要

F 型模式(內容頁面):          Z 型模式(登陸頁面):
████████████████████████      1 ──────────────────► 2
████████                            ↘
████                                     ↘
██                                            ↘
                                   3 ──────────────────► 4

5. 留白 — 隔離創造重要性

.hero { padding: 120px 48px; }  /* Generous space */
.data-table { padding: 12px; }  /* Dense content */

6. 深度與層次 — 向前突出的元素吸引注意力

:root {
  --shadow-sm: 0 1px 2px rgba(0,0,0,0.05);
  --shadow-md: 0 4px 6px rgba(0,0,0,0.1);
  --shadow-lg: 0 10px 15px rgba(0,0,0,0.1);
}

.card { box-shadow: var(--shadow-sm); }
.card:hover { box-shadow: var(--shadow-md); }
.modal { box-shadow: var(--shadow-lg); }

瞇眼測試

瞇著眼看你的設計。你還能看到層級嗎?如果可以,說明層級很強。


間距與節奏

「留白就像空氣:它是設計呼吸所必需的。」— Wojciech Zieliński

間距是設計的隱形結構。一致的間距創造視覺節奏——讓元素感覺彼此屬於一個連貫的系統。

8px 網格

8px 網格是業界標準,因為: - 可均勻分割(8、16、24、32、40、48…) - 適用於常見螢幕密度(1x、1.5x、2x、3x) - 無需計算即可創造一致節奏

:root {
  --space-1: 4px;    /* Tight: icon gaps */
  --space-2: 8px;    /* Compact: inline elements */
  --space-3: 12px;   /* Snug: form fields */
  --space-4: 16px;   /* Default: most gaps */
  --space-6: 24px;   /* Spacious: card padding */
  --space-8: 32px;   /* Section gaps */
  --space-12: 48px;  /* Major sections */
  --space-16: 64px;  /* Page sections */
  --space-20: 80px;  /* Hero spacing */
}

內部與外部間距

內部(padding): 元素內部的空間 外部(margin): 元素之間的空間

原則: 在相關群組內,內部間距通常應大於外部間距。

.card {
  padding: 24px;        /* Internal: spacious */
  margin-bottom: 16px;  /* External: less than padding */
}

元件間距模式

卡片:

.card { padding: 24px; border-radius: 12px; }
.card-header { margin-bottom: 16px; }
.card-title { margin-bottom: 4px; }  /* Tight to subtitle */

按鈕:

.btn { padding: 12px 24px; border-radius: 8px; }
.btn--sm { padding: 8px 16px; }
.btn--lg { padding: 16px 32px; }
.btn-group { display: flex; gap: 12px; }

表單:

.form-row { margin-bottom: 24px; }
.form-label { margin-bottom: 4px; }
.form-help { margin-top: 4px; }
.form-actions { margin-top: 32px; display: flex; gap: 12px; }

間距快速參考

情境 建議間距
圖示到文字 4-8px
標籤到輸入框 4px
表單群組之間 24px
卡片內距 20-24px
卡片間距 16-24px
區塊內距(行動裝置) 48-64px
區塊內距(桌面) 80-96px
按鈕內距(水平/垂直) 24px / 12px

動畫原則

「動畫不是讓圖畫動起來的藝術,而是繪製動作的藝術。」— Norman McLaren

動畫為介面注入生命。做得好,它引導注意力、傳達狀態、創造情感連結。做得差,它令人沮喪且分散注意力。

核心原則

動畫應該感覺是必然的,而不是裝飾性的。

好的動畫: 1. 傳達靜態設計無法表達的內容 2. 透過展示關係來降低認知負擔 3. 感覺自然且符合預期 4. 從有意識的感知中消失

差的動畫: 1. 僅因為「看起來很酷」而存在 2. 拖慢使用者 3. 讓人注意到它自身 4. 造成焦慮或不耐煩

UI 的關鍵原則

1. 預期 — 為使用者準備即將發生的事情。

.button {
  transition: transform 0.1s ease-out;
}

.button:active {
  transform: scale(0.97);  /* Slight press before action */
}

2. 跟隨動作 — 讓動作以類似彈簧的方式自然完成。

.panel {
  transition: transform 0.4s cubic-bezier(0.34, 1.56, 0.64, 1);
}
withAnimation(.spring(response: 0.4, dampingFraction: 0.7)) {
    isOpen = true
}

3. 緩入緩出 — 自然界沒有任何東西以恆定速度移動。

曲線 使用時機 特性
ease-out 進入的元素 快速開始,緩慢停止
ease-in 退出的元素 緩慢開始,快速退出
ease-in-out 狀態變化 全程平滑
linear 載入指示器 連續、機械感

4. 舞台調度 — 將注意力引導到重要的地方。除非作為群組編排,否則一次只應有一個東西移動。

5. 交錯 — 元素應該依序到達,而不是同時出現。

.list-item {
  animation: fadeSlideIn 0.3s ease-out both;
}

.list-item:nth-child(1) { animation-delay: 0ms; }
.list-item:nth-child(2) { animation-delay: 50ms; }
.list-item:nth-child(3) { animation-delay: 100ms; }
.list-item:nth-child(4) { animation-delay: 150ms; }

@keyframes fadeSlideIn {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: translateY(0); }
}

時間指南

持續時間 使用情境 感覺
50-100ms 微互動(懸停、按壓) 即時回饋
150-200ms 簡單狀態變化(切換、選擇) 輕快
250-350ms 中等轉場(面板滑動、卡片翻轉) 流暢
400-500ms 大型動作(頁面轉場、模態框) 從容

效能:黃金法則

只對 transformopacity 進行動畫 — 這些是 GPU 加速的,不會觸發重排。

/* BAD: Animating layout */
.panel { transition: left 0.3s, width 0.3s; }

/* GOOD: Using transform */
.panel { transition: transform 0.3s; }

何時不使用動畫

  1. 使用者啟用了 prefers-reduced-motion css @media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; } }

  2. 動畫沒有傳達任何資訊 — 無謂的旋轉器、彈跳元素

  3. 使用者趕時間 — 錯誤狀態、表單驗證、搜尋結果
  4. 動畫會拖慢重複操作 — 快捷鍵應跳過動畫

動畫快速參考

:root {
  /* Durations */
  --duration-instant: 0.1s;
  --duration-fast: 0.15s;
  --duration-normal: 0.25s;
  --duration-slow: 0.4s;

  /* Easings */
  --ease-out: cubic-bezier(0.0, 0.0, 0.58, 1.0);
  --ease-in: cubic-bezier(0.42, 0.0, 1.0, 1.0);
  --ease-in-out: cubic-bezier(0.42, 0.0, 0.58, 1.0);
  --ease-out-back: cubic-bezier(0.34, 1.56, 0.64, 1);
}

Dieter Rams:十項原則

「少,但更好。」— Dieter Rams

Dieter Rams 是 20 世紀最具影響力的工業設計師。作為 Braun 從 1961 年至 1995 年的設計總監,他創造的產品在數十年後依然歷久彌新。他的作品直接啟發了 Apple 的設計語言。

好設計的十項原則

1. 好設計是創新的 不要複製。將進步的技術與創新設計結合。

2. 好設計使產品有用 每個元素都必須有目的。形式追隨功能。

3. 好設計是美的 美不是膚淺的——它是本質的。我們每天使用的產品影響著我們的幸福感。

4. 好設計使產品易於理解 使用者不應該需要說明書。介面自己教導自己。

5. 好設計是不引人注目的 設計應該支持,而不是壓倒一切。使用者的內容才是主角,而不是你的 UI。

/* Obtrusive: UI competes with content */
.editor {
  background: linear-gradient(135deg, purple, blue);
  border: 3px dashed gold;
}

/* Unobtrusive: UI recedes, content shines */
.editor {
  background: var(--color-background);
  border: 1px solid var(--color-border);
}

6. 好設計是誠實的 不要使用暗黑模式。不要過度承諾。對限制保持透明。

7. 好設計是持久的 避免會快速過時的潮流。經典優於時髦。

時髦的(會過時):              永恆的:
- 極端的玻璃擬態               - 乾淨的字體排版
- 霓虹色、故障效果             - 微妙的層次感
- 激進的漸層                   - 中性調色盤搭配精心挑選的強調色

8. 好設計注重每一個細節 沒有任何東西是隨意的。載入狀態、空狀態、錯誤狀態——全都經過設計。

9. 好設計是環保的 效能就是環保。尊重使用者的注意力。高效的程式碼。

10. 好設計是盡可能少的設計 移除所有不必要的東西。最好的設計是隱形的。


2025 年網頁模式

現代網頁設計運用原生 CSS 功能,在許多情況下消除了對 JavaScript 的需求。

容器查詢

根據容器而非視窗大小來調整組件尺寸。

.card-grid {
  container-type: inline-size;
  container-name: card-grid;
}

.card {
  display: grid;
  gap: 16px;
  padding: 20px;
}

@container card-grid (min-width: 400px) {
  .card {
    grid-template-columns: auto 1fr;
  }
}

@container card-grid (min-width: 600px) {
  .card {
    padding: 32px;
    gap: 24px;
  }
}

:has() 選擇器

根據子元素選擇父元素——這在過去沒有 JavaScript 是不可能的。

/* Card with image gets different padding */
.card:has(img) {
  padding: 0;
}

.card:has(img) .card-content {
  padding: 20px;
}

/* Form group with error */
.form-group:has(.input:invalid) .form-label {
  color: var(--color-error);
}

/* Highlight navigation when on that page */
.nav-item:has(a[aria-current="page"]) {
  background: var(--color-surface);
}

CSS 巢狀結構

無需預處理器的原生巢狀寫法。

.card {
  background: var(--color-surface);
  border-radius: 12px;
  padding: 24px;

  & .card-title {
    font-size: 1.25rem;
    font-weight: 600;
    margin-bottom: 8px;
  }

  & .card-body {
    color: var(--color-text-secondary);
    line-height: 1.6;
  }

  &:hover {
    box-shadow: var(--shadow-md);
  }

  @media (min-width: 768px) {
    padding: 32px;
  }
}

HTMX 整合

無需龐大 JavaScript 框架的伺服器驅動互動性。

<!-- Load content on click -->
<button hx-get="/api/more-items"
        hx-target="#item-list"
        hx-swap="beforeend"
        hx-indicator="#loading">
  Load More
</button>

<!-- Form with inline validation -->
<form hx-post="/api/contact"
      hx-target="#form-response"
      hx-swap="outerHTML">
  <input type="email" name="email"
         hx-post="/api/validate-email"
         hx-trigger="blur"
         hx-target="next .error" />
  <span class="error"></span>
</form>

設計代符系統

一套完整的代符系統,確保應用程式的一致性。

:root {
  /* Colors */
  --color-text: #1a1a1a;
  --color-text-secondary: #666666;
  --color-text-muted: #999999;

  --color-background: #ffffff;
  --color-surface: #f8f9fa;
  --color-surface-elevated: #ffffff;

  --color-border: #e5e7eb;
  --color-primary: #3b82f6;
  --color-primary-hover: #2563eb;

  --color-success: #10b981;
  --color-warning: #f59e0b;
  --color-error: #ef4444;

  /* Typography */
  --font-sans: system-ui, -apple-system, sans-serif;
  --font-mono: "SF Mono", Consolas, monospace;

  --text-xs: 0.75rem;
  --text-sm: 0.875rem;
  --text-base: 1rem;
  --text-lg: 1.125rem;
  --text-xl: 1.25rem;
  --text-2xl: 1.5rem;
  --text-3xl: 2rem;

  --leading-tight: 1.25;
  --leading-normal: 1.5;
  --leading-relaxed: 1.75;

  /* Spacing (8px base) */
  --space-1: 0.25rem;   /* 4px */
  --space-2: 0.5rem;    /* 8px */
  --space-3: 0.75rem;   /* 12px */
  --space-4: 1rem;      /* 16px */
  --space-6: 1.5rem;    /* 24px */
  --space-8: 2rem;      /* 32px */
  --space-12: 3rem;     /* 48px */
  --space-16: 4rem;     /* 64px */

  /* Borders */
  --radius-sm: 4px;
  --radius-md: 8px;
  --radius-lg: 12px;
  --radius-full: 9999px;

  /* Shadows */
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
  --shadow-md: 0 4px 6px rgba(0, 0, 0, 0.07);
  --shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.1);

  /* Transitions */
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --duration-fast: 100ms;
  --duration-normal: 200ms;
}

正確實現深色模式

不要只是反轉顏色——要為深色環境重新設計。

@media (prefers-color-scheme: dark) {
  :root {
    /* Neutrals */
    --color-background: hsl(220, 13%, 10%);
    --color-surface: hsl(220, 13%, 15%);
    --color-surface-elevated: hsl(220, 13%, 18%);
    --color-border: hsl(220, 13%, 23%);

    /* Text (inverted) */
    --color-text: hsl(220, 9%, 93%);
    --color-text-secondary: hsl(220, 9%, 70%);
    --color-text-muted: hsl(220, 9%, 55%);

    /* Adjust saturation for dark mode */
    --color-primary: hsl(220, 80%, 60%);
    --color-success: hsl(142, 70%, 45%);
    --color-error: hsl(0, 80%, 65%);

    /* Shadows in dark mode need adjustment */
    --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.3);
    --shadow-md: 0 4px 6px rgba(0, 0, 0, 0.4);
  }
}

深色模式原則: - 降低大面積區域的飽和度 - 提高強調色的亮度 - 加強陰影(需要更多對比度) - 刻意設計深色模式,而非事後補救


Figma 擷取工作流程

將設計檔案轉換為正式程式碼需要系統性地擷取設計代符——定義您設計語言的顏色、字型、間距和效果。

Figma 變數匯出

Figma 的原生變數功能提供最簡潔的擷取路徑:

匯出步驟: 1. 開啟 Figma 檔案 → 本地變數面板 2. 點擊集合選單 → “Export to JSON” 3. 儲存為 figma-variables.json

JSON 代符結構:

{
  "colors": {
    "primitive": {
      "blue-500": { "value": "#3b82f6", "type": "color" },
      "blue-600": { "value": "#2563eb", "type": "color" }
    },
    "semantic": {
      "primary": { "value": "{colors.primitive.blue-500}", "type": "color" },
      "primary-hover": { "value": "{colors.primitive.blue-600}", "type": "color" }
    }
  },
  "spacing": {
    "1": { "value": "4px", "type": "spacing" },
    "2": { "value": "8px", "type": "spacing" },
    "4": { "value": "16px", "type": "spacing" }
  }
}

代符轉 CSS 轉換

CSS 自訂屬性:

:root {
  /* Primitive colors (direct values) */
  --color-blue-50: #eff6ff;
  --color-blue-100: #dbeafe;
  --color-blue-500: #3b82f6;
  --color-blue-600: #2563eb;
  --color-blue-900: #1e3a8a;

  /* Semantic colors (reference primitives) */
  --color-primary: var(--color-blue-500);
  --color-primary-hover: var(--color-blue-600);
  --color-background: var(--color-white);
  --color-surface: var(--color-gray-50);

  /* Spacing (8px grid) */
  --space-1: 0.25rem;  /* 4px */
  --space-2: 0.5rem;   /* 8px */
  --space-4: 1rem;     /* 16px */
  --space-6: 1.5rem;   /* 24px */
  --space-8: 2rem;     /* 32px */

  /* Typography */
  --font-size-sm: 0.875rem;
  --font-size-base: 1rem;
  --font-size-lg: 1.125rem;
  --line-height-tight: 1.25;
  --line-height-normal: 1.5;

  /* Effects */
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
  --shadow-md: 0 4px 6px rgba(0, 0, 0, 0.07);
  --radius-sm: 4px;
  --radius-md: 8px;
  --radius-lg: 12px;
}

深色模式代符:

@media (prefers-color-scheme: dark) {
  :root {
    --color-background: var(--color-gray-900);
    --color-surface: var(--color-gray-800);
    --color-text: var(--color-gray-100);
    --color-text-secondary: var(--color-gray-400);

    /* Adjusted shadows for dark mode */
    --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.3);
    --shadow-md: 0 4px 6px rgba(0, 0, 0, 0.4);
  }
}

代符轉 SwiftUI 轉換

顏色擴展:

import SwiftUI

extension Color {
    // MARK: - Primitive Colors
    static let blue50 = Color(hex: "eff6ff")
    static let blue500 = Color(hex: "3b82f6")
    static let blue600 = Color(hex: "2563eb")

    // MARK: - Semantic Colors
    static let brandPrimary = Color.blue500
    static let brandPrimaryHover = Color.blue600

    // MARK: - Surface Colors
    static let surfaceBackground = Color(light: .white, dark: Color(hex: "0f172a"))
    static let surfaceElevated = Color(light: Color(hex: "f8fafc"), dark: Color(hex: "1e293b"))
}

extension Color {
    init(hex: String) {
        // Standard hex parsing implementation
    }

    init(light: Color, dark: Color) {
        self.init(UIColor { traits in
            traits.userInterfaceStyle == .dark ? UIColor(dark) : UIColor(light)
        })
    }
}

間距常數:

enum Spacing {
    static let xs: CGFloat = 4    // --space-1
    static let sm: CGFloat = 8    // --space-2
    static let md: CGFloat = 16   // --space-4
    static let lg: CGFloat = 24   // --space-6
    static let xl: CGFloat = 32   // --space-8
}

// Usage
VStack(spacing: Spacing.md) {
    // ...
}
.padding(Spacing.lg)

設計師交接清單

設計師應匯出的內容:

資源類型 格式 備註
顏色 Variables JSON 包含淺色 + 深色模式
字型 Styles export 字體、大小、字重、行高
間距 Variables JSON 記錄基礎單位
圖示 SVG 輪廓線、單色
圖片 PNG @2x/@3x 或 WebP 含壓縮
元件 Figma 連結 供實作時參考

品質關卡標準:

  • [ ] 所有顏色定義為變數(無硬編碼十六進位值)
  • [ ] 字型使用已定義的文字樣式
  • [ ] 間距遵循網格系統(8px 基礎)
  • [ ] 提供深色模式變體
  • [ ] 記錄互動狀態(懸停、活動、停用)
  • [ ] 標註響應式斷點
  • [ ] 註明無障礙需求(對比度)

開發人員收到的內容:

  1. 代符檔案(JSON/CSS/Swift 依平台而定)
  2. 含尺寸的元件規格
  3. 所需格式的資源匯出
  4. 互動文件(狀態、動畫)
  5. 無障礙標註

快速參考表

格式塔原則

原則 規則 用途
鄰近性 相關 = 靠近 表單、區塊
相似性 外觀相同 = 功能相同 按鈕、卡片
圖地關係 清晰的層次分離 對話框、卡片
連續性 跟隨線條 時間軸、對齊
封閉性 大腦會補全形狀 圖示、捲動提示

字型排版

元素 大小 字重 行高
內文 16px 400 1.5-1.7
標題 24-48px 600-700 1.1-1.2
UI 標籤 12-14px 500 1.3-1.4
說明文字 12px 400 1.4

顏色角色

角色 淺色模式 深色模式
背景 #ffffff #0f172a
表面 #f4f5f7 #1e293b
邊框 #e4e6ea #334155
文字 #1a1a2e #f1f5f9
次要文字 #6b7280 #94a3b8
主色 #3b82f6 #60a5fa
成功 #22c55e #4ade80
錯誤 #ef4444 #f87171

間距比例

代符 用途
–space-1 4px 圖示間距
–space-2 8px 行內元素
–space-4 16px 預設間距
–space-6 24px 卡片內距
–space-8 32px 區塊間距
–space-16 64px 頁面區塊

設計檢核表

在發布任何介面之前,請確認:

格式塔

  • [ ] 相關元素比不相關元素更靠近(鄰近性)
  • [ ] 相似功能有相似樣式(相似性)
  • [ ] 前景和背景之間有清晰分離(圖地關係)
  • [ ] 視線自然流過版面(連續性)

字型排版

  • [ ] 基礎字體大小至少 16px
  • [ ] 內文行高為 1.5 以上
  • [ ] 每行字數低於 75 個字元
  • [ ] 層次清晰(可區分 3 個層級)
  • [ ] 全程使用一致的比例

顏色

  • [ ] 所有文字通過 4.5:1 對比度(WCAG AA)
  • [ ] 顏色不是唯一的指示方式(還有圖示/標籤)
  • [ ] 深色模式經過刻意設計
  • [ ] 遵循 60-30-10 分配原則

視覺層次

  • [ ] 能辨識出最重要的第一元素
  • [ ] 視線按預期順序流動
  • [ ] 每個區塊有一個明確的行動呼籲
  • [ ] 字型比例一致

間距

  • [ ] 所有間距使用定義的比例(無隨意數值)
  • [ ] 卡片/元件有一致的內距
  • [ ] 行動裝置間距舒適
  • [ ] 網格對齊一致(8px 基礎)

Dieter Rams 檢核

  • [ ] 有任何東西可以移除嗎?
  • [ ] 每個元素都有功能性目的嗎?
  • [ ] 這在 5 年後會顯得過時嗎?
  • [ ] 我設計了每個狀態嗎?

資源

書籍: - As Little Design as Possible by Sophie Lovell (Dieter Rams) - The Elements of Typographic Style by Robert Bringhurst

工具: - WebAIM Contrast Checker - Type Scale Generator - Figma Tokens Studio — 設計 token 管理

設計系統: - Apple HIG - Material Design 3 - Radix UI - shadcn/ui


設計研究

深入剖析 16 款傑出產品,記錄值得借鑑的設計模式與原則。

開發者工具

產品 關鍵貢獻
Figma 多人協作存在感、情境感知面板
Warp 區塊式終端機、CLI-GUI 橋接
Framer 視覺化響應式設計、屬性控制項
Vercel 深色模式典範、環境狀態指示
Linear 樂觀式 UI、鍵盤優先工作流程
Raycast 擴充系統、快速操作

iOS 原生應用(Apple Design Award 獲獎作品)

產品 關鍵貢獻
Flighty 15 種智慧狀態、Live Activities、資料視覺化
Halide 智慧啟動、手勢控制
Bear 字體排印優先、行內標籤
Craft 原生優先跨平台、巢狀頁面
Things 延遲日期、快速輸入模式

生產力與 AI

產品 關鍵貢獻
Superhuman 100ms 規則、命令面板訓練、練習式新手引導
Perplexity 引用優先 AI、串流階段
Notion 區塊系統、斜線指令
Arc 空間、分割視圖、命令列
Stripe 文件典範、API 設計

本指南透過實踐持續成長。設計原則是永恆的,但其應用會隨著技術與理解而演進。