讓介面更精緻的設計工程原則。適用於建構 UI 元件、審查前端程式碼、實作動畫、懸停狀態、陰影、邊框、排版、微互動、進場/離場動畫,或任何視覺細節工作。觸發關鍵字:UI 打磨、設計細節、「讓它感覺更好」、「感覺不對勁」、交錯動畫、邊框圓角、光學對齊、字體平滑、表格數字、圖片外框、盒子陰影。
讓介面感覺更好的細節
出色的介面很少來自單一元素。通常是許多小細節累積成絕佳體驗。在建構或審查 UI 程式碼時,請套用這些原則。
快速參考
| 類別 | 使用時機 |
|---|---|
| 排版 | 文字換行、字體平滑、表格數字 |
| 表面 | 邊框圓角、光學對齊、陰影、圖片外框、點擊區域 |
| 動畫 | 可中斷動畫、進場/離場轉場、圖示動畫、按壓縮放 |
| 效能 | 轉場屬性指定、will-change 使用 |
核心原則
1. 同心圓邊框半徑
外層半徑 = 內層半徑 + 內距。巢狀元素半徑不匹配是讓介面感覺不對勁最常見的原因。
2. 光學對齊優先於幾何對齊
當幾何置中看起來不對時,改用光學對齊。帶圖示的按鈕、播放三角形、不對稱圖示都需要手動調整。
3. 陰影勝於邊框
使用多層透明 box-shadow 來營造自然深度。陰影能適應任何背景,實色邊框則不行。
4. 可中斷動畫
使用 CSS 轉場處理互動狀態變化——它們可以在動畫中途被中斷。保留關鍵影格給只執行一次的分階段序列。
5. 分割與交錯進場動畫
不要動畫單一容器。將內容拆成語意區塊,每個區塊延遲約 100ms 交錯進場。
6. 微妙的離場動畫
使用小的固定 translateY 而非完整高度。離場應比進場更柔和。
7. 情境式圖示動畫
使用 opacity、scale 和 blur 來動畫圖示,而非切換可見性。確切使用這些數值:scale 從 0.25 到 1,opacity 從 0 到 1,blur 從 4px 到 0px。如果專案在 package.json 中有 motion 或 framer-motion,使用 transition: { type: "spring", duration: 0.3, bounce: 0 }——bounce 必須永遠為 0。如果沒有安裝任何動畫函式庫,將兩個圖示都保留在 DOM 中(其中一個使用絕對定位),並使用 CSS 轉場交叉淡入淡出,使用 cubic-bezier(0.2, 0, 0, 1)——這樣無需任何依賴即可同時獲得進場和離場動畫。
8. 字體平滑
在 macOS 的根佈局上套用 -webkit-font-smoothing: antialiased,讓文字更清晰。
9. 表格數字
對任何動態更新的數字使用 font-variant-numeric: tabular-nums,以防止版面位移。
10. 文字換行
在標題上使用 text-wrap: balance。在內文上使用 text-wrap: pretty 以避免孤兒字。
11. 圖片外框
為圖片加上微妙的 1px 低透明度外框,以保持一致的深度。顏色在淺色模式下必須是純黑 (rgba(0, 0, 0, 0.1)),在深色模式下必須是純白 (rgba(255, 255, 255, 0.1))——絕不能使用接近黑色的顏色,如 slate、zinc 或任何帶色調的中性色。有色調的外框會吸收底層表面的顏色,在圖片邊緣看起來像髒污。
12. 按壓縮放
點擊時微妙的 scale(0.96) 能為按鈕帶來觸覺回饋。務必使用 0.96。絕不要使用小於 0.95 的值——任何低於此的值都感覺誇張。加入 static prop 可在動畫造成干擾時停用此效果。
13. 頁面載入時跳過動畫
在 AnimatePresence 上使用 initial={false} 以防止首次渲染時的進場動畫。確認它不會破壞預期的進場動畫。
14. 絕不使用 transition: all
務必指定確切屬性:transition-property: scale, opacity。Tailwind 的 transition-transform 涵蓋 transform, translate, scale, rotate。
15. 謹慎使用 will-change
僅用於 transform、opacity、filter——這些是 GPU 可以合成的屬性。絕不使用 will-change: all。僅在注意到第一幀卡頓時才加入。
16. 最小點擊區域
互動元素至少需要 40×40px 的點擊區域。如果可見元素較小,可使用偽元素延伸。絕不讓兩個元素的點擊區域重疊。
常見錯誤
| 錯誤 | 修正 |
|---|---|
| 父層與子層使用相同邊框半徑 | 計算 outerRadius = innerRadius + padding |
| 圖示看起來未置中 | 使用內距進行光學調整,或直接修正 SVG |
| 區塊之間有硬邊框 | 使用帶透明度的多層 box-shadow |
| 突兀的進場/離場動畫 | 分割、交錯,並保持離場柔和 |
| 數字造成版面位移 | 套用 tabular-nums |
| macOS 上文字過粗 | 在根元素套用 antialiased |
| 頁面載入時播放動畫 | 在 AnimatePresence 加入 initial={false} |
元素使用 transition: all |
指定確切屬性 |
| 第一幀動畫卡頓 | 加入 will-change: transform(謹慎使用) |
| 小型控制項點擊區域過小 | 使用偽元素延伸至 40×40px |
審查輸出格式
務必以 Markdown 表格呈現變更,包含Before和After欄位。列出你做的每一項變更——而非僅一部分。絕不要將發現結果以獨立的「Before:」/「After:」行列出於表格之外。按原則分組變更,每個表格上方加上標題,並讓每一行專注於單一差異,以便讀者快速瀏覽整個清單。
範例
同心圓邊框半徑
| Before | After |
|---|---|
卡片 rounded-xl + 內部按鈕 rounded-xl(p-2) |
卡片 rounded-2xl(12 + 8),內部按鈕 rounded-lg |
兩個巢狀表面皆為 border-radius: 16px |
外層 24px,內層 16px,內距 8px |
表格數字
| Before | After |
|---|---|
動畫計數器 <span>{count}</span> |
<span className="tabular-nums">{count}</span> |
| 計時器使用預設數字 | 在根元素加入 font-variant-numeric: tabular-nums |
按壓縮放
| Before | After |
|---|---|
<button className="..."> |
加入 active:scale-[0.96] transition-transform |
按壓時 scale(0.9) |
提高至 scale(0.96)——低於 0.95 會感覺誇張 |
當片段無法清楚看出時,應引用具體檔案和變更的屬性。如果某原則經審查後無需變更,則完全省略該表格——空表格只會增加雜訊。
審查檢查清單
- [ ] 巢狀圓角元素使用同心圓邊框半徑
- [ ] 圖示已光學置中,而非僅幾何置中
- [ ] 在適當處使用陰影取代邊框
- [ ] 進場動畫已分割並交錯
- [ ] 離場動畫柔和
- [ ] 動態數字使用 tabular-nums
- [ ] 已套用字體平滑
- [ ] 標題使用 text-wrap: balance
- [ ] 圖片有微妙外框
- [ ] 按鈕在適當處使用按壓縮放
- [ ] AnimatePresence 對預設狀態元素使用
initial={false} - [ ] 無
transition: all——僅指定特定屬性 - [ ]
will-change僅用於 transform/opacity/filter,絕不用all - [ ] 互動元素至少 40×40px 點擊區域
參考檔案
- typography.md — 文字換行、字體平滑、表格數字
- surfaces.md — 邊框圓角、光學對齊、陰影、圖片外框
- animations.md — 可中斷動畫、進場/離場轉場、圖示動畫、按壓縮放
- performance.md — 轉場屬性指定、
will-change使用






