GIGA UI:沉穩、精確、有生命力
此技能可將一行 UI 請求轉化為精緻、可投入生產的介面。視覺語言靈感來自 @marcelkargul(Kargul Studio)的公開設計作品:沉穩、近乎單色的產品 UI、非常精確的排版、用柔和的層疊陰影取代厚重的邊框、一個自信的強調色,以及快速、物理性且絕不為裝飾而存在的動畫。
它適用於任何編碼模型與任何技術棧。範例使用 React + Tailwind + Motion(motion/react),每個範例都有純 CSS 等價寫法。
下方使用以下來源標記: [seen] 直接從他的貼文/圖片中觀察到,或在標題中陳述。 [inferred] 從觀察到的內容(從螢幕截圖測量或推斷)進行的合理推論。 [expert] 來自 Motion 文件、Emil Kowalski、Apple HIG 的一般動畫/UX 最佳實踐。非來自他的貼文。
1. 設計哲學
- 如果可以移除,就移除它。 [seen,標題:「每個畫面。每個元件。每個影格。如果它不需要存在,就不應該存在。簡單總是困難,但簡單總是勝利。」]
- 排版承擔了大部分的工作。 [seen:「只要精通排版,你就可以讓任何東西看起來好看。」] 使用一種字體家族(網頁默認 Inter,可選 Geist;iOS 風格的行動裝置使用 SF Pro Rounded),且最多使用兩種字重 [seen:「sf pro rounded,最多 2 種字重,保持簡單」]。
- 白色、黑色和陰影。 [seen:「沒有動畫,沒有漸層,沒有花俏效果。只有 FFFFFF、000000 和一些陰影。這就是設計的巔峰。」] 大部分色板是中性灰色。顏色僅用於表達意義,例如狀態、類別或唯一的主要操作。
- 深度來自柔和的層疊陰影和髮絲線,而不是厚重的邊框。 [seen:「這個按鈕只需要 3 個陰影!」以及 §3 中的次要按鈕配方]
- 動畫是產品的一部分,不是裝飾。 [seen:「貫穿始終的微互動」、「微妙的載入動畫。不過度,剛剛好」、「每個網站都需要這種層級的動畫」、「想法 → 設計 → 動畫」]。僅為解釋變更、確認操作或引導注意而進行動畫 [expert]。
- 手動打磨最後的 10%。 [seen:他的流程是「在 Figma 中設計,在 Claude 的幫助下建構,花費數小時手動修正小細節並改善程式碼品質」]。§9 中的 QA 檢查清單就是那最後的 10%。
- 乾淨勝過聰明。 他的標題反覆回歸到「乾淨」、「沉穩」和「簡單」這些詞(例如,「一個沉穩清單中的所有任務」)。即使資料量很大,畫面也應該感覺沉穩。
2. 觀察到的風格(他的作品實際上長怎樣)
2.1 排版
- 字體家族: Inter(此技能的預設)和 Geist(可選替代方案)。[seen:「在試過數百種字體後,我意識到沒有什麼比得上 Inter 和 Geist。」;玩笑貼文:初級和高級設計師都使用「Inter, Geist」]。行動應用程式使用 SF Pro Rounded [seen,數篇貼文]。他也推薦 Google Sans Rounded 作為 SF Pro Rounded 的跨平台替代方案 [seen,回覆]。等寬字體(類似 Geist Mono)用於大數字、股票代碼和程式碼 [seen:加密貨幣應用程式餘額、Statsnap KPI 卡片、側邊欄導航變體]。品牌和行銷作品有時使用襯線展示字體(編輯過渡襯線,輕字重)[seen:金融科技登陸頁「Every payment protected…」,VC 登陸頁面]。
- 字距(他的精確數字,使用 Geist 示範;同樣適用於 Inter,他也曾以 −6% 示範) [seen]:
- 16px → 0%
- 36px → −3%
- 100px+ → −5% 到 −6%
- 「永不負數規則適用於內文。在 100px+ 時,預設間距看起來太鬆散。」
- SF Pro Rounded:+1% 字母間距 [seen,字體樣本]。
- 字重: Regular (400) 和 Medium (500) 承擔了幾乎所有產品 UI。Semibold (600) 用於標題和數字。Bold/Black 僅用於大型展示標題 [inferred,從螢幕截圖推斷]。
- 產品 UI 中的尺寸 [inferred,從 1× 螢幕截圖測量]:正文和表格文字 13–14px,次要/元資料 12–13px,章節標籤 11–12px 大寫或小型大寫灰色(例如「WORKSPACE」、「PINNED TOOLS」),頁面標題 18–24px Medium,KPI 數字 24–32px,英雄標題 48–72px 並帶有負字距。按鈕為 14px Medium [seen:「Geist/14/Medium」]。
- 文字顏色: 主要近乎黑色(#171717–#1F1F1F),次要中灰色(#6B6B6B–#737373),三級/佔位符(#A3A3A3)。標籤使用深色調文字搭配淺色調背景,而非白色文字搭配飽和填充色 [seen:「Do / Don't」貼文:「深色文字極大地改善了整體可讀性。」]。
2.2 色彩
從螢幕截圖(近似值)取樣 [seen/inferred]:
| 角色 | 亮色 | 暗色 |
|---|---|---|
| 畫布 / 頁面 | #FFFFFF | #0D0D0D–#121212 |
| 微妙表面(側邊欄、面板、行動背景) | #F7F7F7 / #F4F4F4 / #FAFAFA | #1A1A1A–#1E1E1E |
| 展示背板(在 Mockup 後方) | #E5E5E5–#EDEDED,中灰色 #8A8A8A | #1F1F1F–#262626 |
| 髮絲邊框 | #ECECEC / #EBEBEB | rgba(255,255,255,0.08) |
| 主要文字 | #171717 | #FAFAFA |
| 次要文字 | #737373 | #A1A1A1 |
強調色(每個產品使用一個,從不一次使用多種)[seen]:
- 紫羅蘭色
#7B3AEC(Underlay 註冊、引導流程),也有靛藍色#5B5BF0變體 - 藍色
#255CD1/ iOS 藍色#2F7BF6(計算機、日曆、Statsnap) - 橙色
#FF5A1F/#F97316(Plunio、Nexora) - 藍綠色
#0F766E-ish(AI 管道、AIData) - 萊姆色
#B4F05A搭配近乎黑色(程式碼編輯器「Start」按鈕、Soma 品牌) - 珊瑚紅
#F2435A(睡眠應用程式) - 純黑
#0A0A0A作為中性應用程式的主要按鈕顏色(睡眠應用程式、計算機「=」、「Deploy v13」、「New event」)[seen]
語意色調 [seen]:綠色 #16A34A 文字搭配 #ECFDF3 背景;紅色 #DC2626 搭配 #FEF2F2 背景;琥珀色/橙色搭配 #FFF4E5 背景;藍色搭配 #EEF4FF 背景。頭像首字母位於帶有更深同色調文字的柔和圓圈上(「SW」、「AJ」、「MP」)。
漸層: 很少使用但用得恰到好處 [seen:「使用漸層的藝術」]。按鈕會有微妙的上到下漸層(次要按鈕為 #FFFFFF → #F7F7F7;主要按鈕頂部稍亮)。英雄插圖使用模糊的多彩色塊搭配 Plus-Darker 混合模式,再加上噪點/顆粒疊加 [seen:英雄插圖系列貼文]。
2.3 形狀、間距、深度
- 圓角半徑 [seen and inferred]:小型控件和按鈕 8–10px [seen:「30px 高度,10px 半徑」];輸入框 10–12px;卡片 12–16px;模態視窗和命令面板 20–24px;行動表單和電話卡片 24–32px;藥丸狀和晶片完全圓角。行動按鈕通常是完整藥丸狀 [seen]。
- 間距: 4px 基礎網格。常見間距為 4/8/12/16/24/32/48 [inferred]。內容周圍有大量留白;密集的表格行高仍約為 40–48px [inferred]。
- 控件高度 [seen/inferred]:緊湊型桌面按鈕 30–32px,標準 36–40px,行動主要 CTA 48–56px。
- 邊框: 1px 髮絲線,採用非常淺的灰色。邊框通常由一個 0 模糊 1px 擴散的陰影構成,而非
border[seen:次要按鈕配方]。 - 陰影 [seen]:次要按鈕陰影 =
0 1px 2px rgba(40,40,40,.08), 0 0 0 1px #ECECEC。浮動表面(彈出視窗、面板、工具提示)使用一個大而非常柔和的環境陰影加上髮絲線。暗色工具提示置於亮色 UI 上 [seen:Statsnap 圖表工具提示、「Task completed · Undo」提示]。 - 行動裝置: 畫板 430×932 [seen],頂部欄 40–44px 圓形圖示按鈕,在灰色畫布上分組的「嵌入」列表卡片,浮動藥丸狀標籤欄 [seen]。
2.4 佈局模式 [seen]
- SaaS 應用程式外殼: 左側邊欄(220–260px)位於微妙灰色背景上,分組導航帶有小寫大寫灰色標籤,啟用項目 = 白色藥丸帶柔和陰影(亮色)或
#1E1E1E填充(暗色);主要內容位於白色背景上,帶有細頂部欄(麵包屑Home > Transaction,帶有/提示的搜尋框,圖示按鈕)。有時會有細長的圖示軌道(48–56px)代替。 - 表格上方的篩選晶片行:
Range Last 30 days ▾、Scope All tools ▾。標籤為灰色,值為深色。 - 表格: 無斑馬紋,髮絲線行分隔線,小的灰色標題文字,色調狀態藥丸,頭像 + 名稱 + 電子郵件堆疊,右對齊數字,列表數字。
- KPI 卡片: 標籤、大數字(通常為等寬)、Delta 藥丸(
▲ +14.7% vs last year)。 - 驗證/引導流程: 分割卡片。左側為表單(柔和圓圈中的 Logo、標題、副標題、Google 按鈕、「或」分隔線、輸入框、主要按鈕),右側為灰色面板中的產品預覽,帶有輪播點 [seen:「just designed the perfect signup page」]。
- 命令面板: 24px 半徑,帶有
ESC按鍵提示的搜尋行,篩選藥丸,分組結果,鍵盤圖例頁腳 [seen]。 - 行動引導流程: 分段進度條 +「1/5」,置中粗體問題,帶有圓形勾選的可選選項行,黏性藥丸 CTA [seen]。
- 登陸頁英雄: 浮動藥丸導航欄,小的「Backed with X」徽章,簡短有力的標題(有時是全大寫的無襯線字體,有時是襯線字體),深色主要 + 白色次要按鈕,下方為大型插圖 [seen]。
2.5 圖示與插圖 [seen]
- 圖示:細線條輪廓圖示(類似 Lucide/Phosphor,~1.5px 線條粗細,UI 中 16–18px),預設為灰色,啟用時變深。
- 小的彩色應用程式圖示磁貼(帶有漸層和字形的圓角正方形)用於功能卡片和分類。
- 插圖風格:(a) 等距線條藝術,位於虛線網格上,單色;(b) 鮮豔的漸層帶/流,位於顆粒感粉彩背景上,帶有等距網格和浮動紙屑;(c) 友好的平面陰影點綴插圖和 3D 風格的表情符號圖示,適用於消費者和行動應用程式;(d) 擬物化點綴(一個縫合皮革錢包,裡面放著一張卡片)。
- 他的動畫流程:「在 Figma 中繪製插圖 → 在 AE/Rive 中製作動畫 → 如果使用 AE 則導出到 Lottie → 在網站上實現」。在某個項目中,他使用了「Figma… Rive 用於動畫,Next.js + Sanity」。英雄區域通常需要「設計 + 插圖 + 動畫」[seen]。
2.6 暗色與亮色模式 [seen]
他兩種模式都使用,並提供匹配的組合(「亮色/暗色模式」、「figma tokens are so useful!」)。亮色是生產力 SaaS 的預設。暗色用於加密貨幣/交易、程式碼編輯器、側邊欄和行銷橫幅。暗色表面以 ~6–10 亮度增量逐步提高(#0D0D0D → #121212 → #1A1A1A → #222),而非到處都是純黑。
3. 設計代碼(CSS 變數)
將此貼到全域樣式表中。Tailwind 使用者可以在 @theme(v4)或 theme.extend(v3)中映射這些。
:root {
/* 字體 */
--font-sans: "Inter", "Geist", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
--font-mono: ui-monospace, "Geist Mono", "SF Mono", Menlo, monospace;
--font-rounded: "SF Pro Rounded", ui-rounded, "Google Sans Rounded", var(--font-sans);
--text-xs: 12px; --text-sm: 13px; --text-base: 14px; --text-md: 16px;
--text-lg: 18px; --text-xl: 24px; --text-2xl: 32px; --text-3xl: 48px;
--text-4xl: 64px; --text-5xl: 96px;
--tracking-body: 0; /* <= 16px */
--tracking-tight: -0.01em;/* 18–24px */
--tracking-title: -0.03em;/* ~36px (his rule) */
--tracking-display: -0.055em; /* 100px+ (his rule: -5% to -6%) */
--weight-regular: 400; --weight-medium: 500; --weight-semibold: 600;
/* 中性色(亮色) */
--bg: #ffffff;
--bg-subtle: #f7f7f7;
--bg-muted: #f0f0f0;
--bg-backdrop: #e8e8e8;
--border: #ececec;
--border-strong: #e0e0e0;
--fg: #171717;
--fg-secondary: #737373;
--fg-tertiary: #a3a3a3;
--fg-inverse: #ffffff;
/* 強調色:每個產品選擇一種 */
--accent: #7b3aec; /* 紫羅蘭色;替代方案:#255cd1 藍色、#ff5a1f 橙色、#0a0a0a 黑色 */
--accent-hover: color-mix(in oklab, var(--accent), black 8%);
--accent-soft: color-mix(in oklab, var(--accent), white 90%);
--accent-fg: #ffffff;
--ring: color-mix(in oklab, var(--accent), transparent 65%);
/* 語意色(深色文字搭配柔色調) */
--success: #16a34a; --success-soft: #ecfdf3;
--danger: #dc2626; --danger-soft: #fef2f2;
--warning: #d97706; --warning-soft: #fff7e6;
--info: #2563eb; --info-soft: #eef4ff;
/* 間距(4px 網格) */
--space-1: 4px; --space-2: 8px; --space-3: 12px; --space-4: 16px;
--space-5: 20px; --space-6: 24px; --space-8: 32px; --space-10: 40px;
--space-12: 48px; --space-16: 64px; --space-24: 96px;
/* 圓角 */
--radius-xs: 6px; --radius-sm: 8px; --radius-md: 10px; --radius-lg: 12px;
--radius-xl: 16px; --radius-2xl: 20px; --radius-3xl: 24px; --radius-full: 9999px;
/* 高度 */
--h-control-sm: 30px; --h-control: 36px; --h-control-lg: 44px; --h-cta-mobile: 52px;
/* 陰影(分層、柔和;透過擴散產生髮絲線) */
--hairline: 0 0 0 1px var(--border);
--shadow-xs: 0 1px 2px rgb(40 40 40 / 0.08);
--shadow-btn: 0 1px 2px rgb(40 40 40 / 0.08), 0 0 0 1px #ececec; /* 他的次要按鈕 */
--shadow-btn-primary: inset 0 1px 0 rgb(255 255 255 / 0.18), 0 1px 2px rgb(0 0 0 / 0.16), 0 0 0 1px color-mix(in oklab, var(--accent), black 12%);
--shadow-card: 0 1px 2px rgb(0 0 0 / 0.04), 0 0 0 1px var(--border);
--shadow-pop: 0 0 0 1px rgb(0 0 0 / 0.06), 0 8px 24px -4px rgb(0 0 0 / 0.10), 0 2px 6px rgb(0 0 0 / 0.04);
--shadow-modal: 0 0 0 1px rgb(0 0 0 / 0.06), 0 24px 64px -12px rgb(0 0 0 / 0.18);
--shadow-focus: 0 0 0 3px var(--ring);
/* 動畫(參見 §5) */
--ease-out: cubic-bezier(0.23, 1, 0.32, 1); /* 強緩出(Emil Kowalski) */
--ease-in-out: cubic-bezier(0.77, 0, 0.175, 1); /* 用於螢幕上的移動 */
--ease-drawer: cubic-bezier(0.32, 0.72, 0, 1); /* 類似 iOS 的抽屜(Vaul) */
--ease-standard: cubic-bezier(0.2, 0, 0, 1);
--dur-instant: 100ms; --dur-fast: 150ms; --dur-base: 200ms;
--dur-moderate: 250ms; --dur-slow: 350ms; --dur-page: 500ms;
}
[data-theme="dark"], .dark {
--bg: #0d0d0d;
--bg-subtle: #141414;
--bg-muted: #1c1c1c;
--bg-backdrop: #0a0a0a;
--border: rgb(255 255 255 / 0.08);
--border-strong: rgb(255 255 255 / 0.14);
--fg: #fafafa;
--fg-secondary: #a1a1a1;
--fg-tertiary: #6b6b6b;
--shadow-btn: inset 0 1px 0 rgb(255 255 255 / 0.06), 0 0 0 1px rgb(255 255 255 / 0.12);
--shadow-btn-primary: inset 0 1px 0 rgb(255 255 255 / 0.10), 0 1px 2px rgb(0 0 0 / 0.24), 0 0 0 1px var(--accent);
--shadow-card: 0 1px 2px rgb(0 0 0 / 0.08), 0 0 0 1px rgb(255 255 255 / 0.08);
--shadow-pop: 0 0 0 1px rgb(255 255 255 / 0.08), 0 8px 24px -4px rgb(0 0 0 / 0.24), 0 2px 6px rgb(0 0 0 / 0.08);
--shadow-modal: 0 0 0 1px rgb(255 255 255 / 0.06), 0 24px 64px -12px rgb(0 0 0 / 0.40);
}
4. 元件配方
備註: 這些是當前 UI 庫與框架的主流模式。
4.1 按鈕
主要按鈕
- 14px Medium(桌面)或 16–18px(行動裝置),填充色為
var(--accent),白色文字,var(--radius-sm)圓角。 - 陰影:使用
var(--shadow-btn-primary),頂部有微妙的高光inset。 - 啟用懸停時:使用
var(--accent-hover)背景。 - 內邊距:水平
16px(桌面)/24px(行動裝置),上下0配合控制高度。
次要按鈕
var(--h-control)高度,var(--radius-sm)圓角。- 陰影:
var(--shadow-btn)(0 1px 2px擴散陰影 + 1px 髮絲線)。 - 懸停時變深(0.5px 實色邊框或更深背景)。
幽靈/文字按鈕
- 無背景或邊框,
var(--fg-secondary)文字。 - 懸停時背景設為
var(--bg-subtle)。
圖示按鈕
- 方形,邊長等於控制高度,
var(--radius-sm)。 - 所有樣式同文字按鈕或次要按鈕。
行動主要 CTA
- 全寬
var(--h-cta-mobile)高度,16–18px Medium,var(--radius-lg)圓角。 - 使用藥丸狀(
--radius-full)作為明確的 iOS 風格。
4.2 輸入框
- 標籤:
var(--text-sm)var(--weight-medium),var(--fg)。12px 間距到輸入框。 - 輸入框本體:
var(--h-control)高度,var(--text-base),var(--radius-md),內邊距12px。 - 邊框:使用
var(--hairline)。聚焦時:使用var(--shadow-focus)和var(--accent)邊框。 - 狀態:錯誤 =
var(--danger)邊框 +var(--danger-soft)背景。成功 =var(--success)邊框。 - 佔位符文字:
var(--fg-tertiary)。 - 描述/輔助文字:
var(--text-sm)var(--fg-secondary),輸入框下方4px。 - 輸入框內圖示:保留
16px空間,置於左/右內邊距。
4.3 卡片
var(--radius-xl)圓角,var(--shadow-card)陰影,12–16px內邊距。- 無實色邊框。改用間距來建立分組。
- 可選的頂部髮絲線用於堆疊中的區隔。
4.4 彈出視窗/工具提示
var(--radius-xl)或var(--radius-2xl)圓角。- 陰影:
var(--shadow-pop)。 - 工具提示:
11-12px文字,深色背景(#1f1f1f),4px內邊距,8px圓角。
4.5 切換開關
- 軌道:
36×20px,var(--radius-full),var(--border)。 - 啓用時:
var(--accent)軌道。14×14px圓形白色拇指按鈕,從左側偏移3px。
4.6 狀態標籤
var(--text-xs)var(--weight-medium),4px水平內邊距,var(--radius-xs)圓角。- 模式:純填充色(白色文字)或色調背景色(深色文字)。採用色調模式。
- 中立:
var(--bg-muted)var(--fg-secondary)。成功/錯誤/警告/資訊:使用語意色。
4.7 進度條
- 容器:全寬
8px高,var(--radius-full),var(--border)背景。 - 填充:
var(--accent),動畫width搭配var(--dur-moderate)和var(--ease-out)。 - 可選:百分比標籤在進度條右側
4px。
4.8 前導圖示的列表項目
- 佈局:圖示(
24–28px,帶var(--radius-sm)圓角容器)→12px間距 → 文字堆疊。 - 文字:標題行
var(--text-base)var(--weight-medium),副標題行var(--text-sm)var(--fg-secondary)。
5. 互動與動畫配方
5.1 通用 CSS 變數
.class {
transition: all var(--dur-fast) var(--ease-out);
/* 或針對特定屬性: */
transition: transform var(--dur-fast) var(--ease-out),
opacity var(--dur-fast) var(--ease-out),
background-color var(--dur-fast) var(--ease-out),
box-shadow var(--dur-fast) var(--ease-out);
}
5.2 懸停與按下效果
按鈕懸停:
translateY(-1px)和增強陰影(var(--shadow-btn)→ 更深,或者增大 y 偏移)。
按下(active):
scale(0.97)搭配var(--dur-instant)。
卡片懸停:
translateY(-2px),var(--shadow-pop),var(--dur-slow)。
輸入框聚焦:
var(--shadow-focus)和邊框顏色為var(--accent)。
連結懸停:
- 文字顏色變為
var(--accent)。可選底線:background-size: 100% 1px。
5.3 進入/退出動畫
淡入(元件進入)
.fade-in {
animation: fadeIn var(--dur-moderate) var(--ease-out) forwards;
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(4px); }
to { opacity: 1; transform: translateY(0); }
}
縮放淡入(模態視窗、面板)
.scale-fade-in {
animation: scaleFadeIn var(--dur-base) var(--ease-out) forwards;
}
@keyframes scaleFadeIn {
from { opacity: 0; transform: scale(0.96); }
to { opacity: 1; transform: scale(1); }
}
從下方滑入(選單、行動表單)
.slide-up {
animation: slideUp var(--dur-moderate) var(--ease-drawer) forwards;
}
@keyframes slideUp {
from { transform: translateY(100%); }
to { transform: translateY(0); }
}
從側邊滑入(導航抽屜)
.slide-in-left {
animation: slideInLeft 300ms var(--ease-drawer) forwards;
}
@keyframes slideInLeft {
from { transform: translateX(-100%); }
to { transform: translateX(0); }
}
Motion 元件版本(motion/react)
import { motion, AnimatePresence } from "motion/react";
<motion.div
initial={{ opacity: 0, y: 8 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: -8 }}
transition={{ duration: 0.2, ease: [0.23, 1, 0.32, 1] }}
>
{children}
</motion.div>
// 卡片的縮放淡入
<motion.div
initial={{ opacity: 0, scale: 0.96 }}
animate={{ opacity: 1, scale: 1 }}
exit={{ opacity: 0, scale: 0.96 }}
transition={{ duration: 0.15, ease: [0.23, 1, 0.32, 1] }}
/>
5.4 清單與疊代(Stagger)
<List>
{items.map((item, i) => (
<motion.li
key={item.id}
initial={{ opacity: 0, y: 8 }}
animate={{ opacity: 1, y: 0 }}
transition={{ delay: i * 0.04, duration: 0.2, ease: [0.23, 1, 0.32, 1] }}
/>
))}
</List>
5.5 數字動畫(計數器)
function AnimatedCounter({ value, duration = 0.5 }: { value: number; duration?: number }) {
const [display, setDisplay] = useState(value);
useEffect(() => {
const start = display;
const end = value;
const startTime = performance.now();
const animate = (now: number) => {
const elapsed = now - startTime;
const progress = Math.min(elapsed / (duration * 1000), 1);
const eased = 1 - Math.pow(1 - progress, 3);
setDisplay(Math.round(start + (end - start) * eased));
if (progress < 1) requestAnimationFrame(animate);
};
requestAnimationFrame(animate);
}, [value, duration]);
return <span>{display.toLocaleString()}</span>;
}
5.6 載入狀態
骨架屏: 使用 var(--bg-subtle) 背景搭配脈衝動畫。
@keyframes pulse {
0%, 100% { opacity: 1; }
50% { opacity: 0.5; }
}
.skeleton {
background: var(--bg-muted);
border-radius: var(--radius-sm);
animation: pulse 1.5s var(--ease-in-out) infinite;
}
微調器: SVG 圓弧搭配旋轉動畫。
@keyframes spin {
to { transform: rotate(360deg); }
}
.spinner {
animation: spin 1s linear infinite;
}
5.7 頁面轉場
包裹路由內容。
<AnimatePresence mode="wait">
<motion.div
key={location.pathname}
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
transition={{ duration: 0.15 }}
>
<Outlet />
</motion.div>
</AnimatePresence>
6. 提示:如何引導 AI
要充分利用此技能:
- 將提示範圍縮小到一個畫面或元件。 不要在一個視窗中要求建立一個完整的應用程式。
- 指定上下文:「儀表板 KPI 卡片」、「設定頁面」、「登入畫面」、「個人資料表單」。
- 選擇你的強調色。 紫色、藍色、橙色、黑色。如果不指定,AI 會猜測(通常選藍色或紫色)。
- 選擇亮色或暗色模式。 如果不指定,AI 會輸出兩者,這可能不是你想要的。
- 如果你有 Logo 或品牌資產,請提供。 品牌顏色、商標表現方式、版權字體。
- 要求完成帶有所有互動和載入狀態的 React + Tailwind 或類似內容。
- 明確要求應對此任務! 好的提示開頭:「使用 GIGA UI 技能為財務應用程式設計一個 KPI 卡片行,採用亮色模式、紫色強調色、Inter 字體。」
7. 實作細節
7.1 函數
- 建立一個
cn()工具函數(使用clsx和tailwind-merge)用於條件式 className 合併。 - 建立一個
formatNumber()工具函數用於數字格式化($、%、逗號、縮寫)。 - 使用
useId()鉤子獲取可訪問的 ID。
7.2 全局樣式
全局排版、CSS 變數和重置。Tailwind base 層是放置非 Tailwind 變數和基礎樣式的自然位置。
@layer base {
* { box-sizing: border-box; }
body {
font-family: var(--font-sans);
font-size: var(--text-base);
line-height: 1.5;
color: var(--fg);
background: var(--bg);
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
}
7.3 檔案結構(React 範例)
components/
ui/
button.tsx
input.tsx
card.tsx
layout/
sidebar.tsx
topbar.tsx
page.tsx
features/
kpi-card.tsx
data-table.tsx
auth-form.tsx
8. 檢測清單:辨識風格
測試你的 UI 是否處於 GIGA UI 語義空間:
- 一個字體家族,最多兩種字重?
- 幾乎沒有顏色(大面積白色/灰色,一個強調色)?
- 沒有厚重的邊框(改為使用髮絲線或陰影)?
- 非常精確的排版(尺寸、間距、字距)?
- 內容周圍有空氣感(間距)?
- 動畫是否服務於功能(解釋、確認、引導)?
9. 品質檢查清單
交付 UI 前請逐一檢查:
邊緣情況
- 最小/最大內容測試(短名稱、長名稱、極短內容、極長內容)
- 清空狀態(列表、表格、搜尋結果)
- 錯誤狀態(表單驗證、API 錯誤)
- 邊界值(輸入最大值、數字格式化)
- 溢位(文字截斷、水平滾動)
載入
- 骨架屏(不僅是旋轉器)用於內容區域
- 按鈕具有載入微調器,同時保持寬度
- 影像延遲載入
- 無內容閃爍(使用最小高度)
空白與對齊
- 一致的間距(4px 網格)
- 文字、圖示、邊緣對齊
- 影像無變形(保持長寬比)
- 容器之間平衡的留白
可訪問性
- 焦點狀態(
:focus-visible環)在鍵盤導航上清晰可見 - 所有輸入框有標籤,圖示按鈕有
aria-label - 表單欄位有關聯的錯誤訊息
- 顏色對比度(文字對背景)通過 WCAG AA 標準
- 互動元素的角色和狀態
- 不需要 JavaScript 也能閱讀內容
暗色模式
- 所有顏色映射都已轉換
- 無遺漏的硬編碼淺色值
- 陰影感覺正確(在暗模式下,更像光源而非陰影)
-
color-scheme設定正確 - 影像在暗模式下不過曝
10. 來源
- 公共作品: Marcel Kargul 的 Dribbble、Instagram、個人網站、Behance。
- 他的動畫工具: Figma、Rive、AE、Lottie、Next.js + Sanity。
- 相關設計典範: Emil Kowalski(vaul、cmdk、圍繞
dialog標籤的 CSS 動畫)、Paco Coursey、Apple HIG、Linear 設計。