---
schemaVersion: 1
slug: gp-233-20260617-polished-ui-rules
ticketId: GP-233
lang: zh-tw
title: AI 做的介面一眼就被看穿，差的那一點是品味
summary: 你不能對模型打『做得精緻一點、滑順一點』然後就拿到精緻的介面。kvnkld 把他做出那些漂亮元件的整套規則攤開來——緩動曲線、設計變數、物理拖曳、分層陰影、98% 的按壓——核心只有一句：把形容詞換成數字。模型是一雙神手，但最後那 10% 的品味還是你的。
originalDate: 2026-06-16
translatedDate: 2026-06-17
source: "@kvnkld on X"
sourceUrl: https://x.com/kvnkld/status/2066863634949779464
author: null
authorshipNote: null
canonicalUrl: https://gu-log.vercel.app/posts/gp-233-20260617-polished-ui-rules
status: published
replacementTicketId: null
replacementUrl: null
---

# AI 做的介面一眼就被看穿，差的那一點是品味

> **來源:** [@kvnkld on X](https://x.com/kvnkld/status/2066863634949779464)

有一種介面，滑過去三秒就知道是 AI 生的。說不上哪裡怪，但就是怪。按鈕點下去硬邦邦、東西冒出來像被人開關燈一樣啪一下亮、卡片浮在背景上像貼紙。每個元素單看都對，合起來就是差一口氣。

[kvnkld](https://x.com/kvnkld/status/2066863634949779464) 常被人追問：那些貼出來的元件怎麼做到這麼精緻？到底是下了什麼 [prompt](https://gu-log.vercel.app/glossary#prompt)？他乾脆把整套規則攤開來，而開場第一句就先把幻想戳破：

> 精緻不是一個你能下指令拿到的功能。你沒辦法打「做得高級一點、滑順一點」然後就抵達那裡。

模型是一雙厲害到不可思議的手，但品味、規則、還有那上百個微小的決定，仍然握在人的手上。下面這整套，就是他做那些元件時真正在用的東西。他說：全部拿去抄。

> **Mogu 想補充：**
>
> 這句話值得裱框。一堆人用 AI 做東西的方式，是把自己腦中那團模糊的「我想要它看起來厲害」原封不動丟給模型，然後對著吐回來的成品皺眉：欸，不是這個感覺。
>
> 問題是「這個感覺」從來沒被你說出口過。你心裡的「高級」可能是 280 毫秒的緩動加一點點過衝，但你嘴上只給了「高級」兩個字——模型只好猜，猜出來的就是那種人人都看過、誰都不會記得的平庸版本。形容詞是你偷懶的藉口，模型只是忠實地把你的偷懶顯影出來而已。(¬‿¬)

## 整套規則底下只有一條：把形容詞換成數字

如果整篇只能記一件事，記這個。kvnkld 的十條規則拆開來各有招式，但底層全是同一個動作——嘴上每講出一個形容詞，就要在心裡把它換算成一個可以直接寫進 CSS 的數字。「滑順」沒有意義；「`cubic-bezier(0.22, 1, 0.36, 1)`，280 毫秒」才做得出來。具體，就是整場遊戲的全部。

而最能體現這件事的，是他擺在第一條、也最在意的東西：**緩動曲線**。

「這是 LLM 做的」跟「這是有品味的人做的」之間，最大的單一差別就是緩動——一個動作怎麼起步、怎麼加速、怎麼停下來。瀏覽器內建的那幾個預設（`ease`、`ease-in-out`）一用上去，整個介面就寫滿了「通用罐頭」四個字。kvnkld 從來不碰它們，而是把一組自家的緩動鎖成設計變數，每個專案都重複用同一套：

```css
:root {
  --ease-smooth: cubic-bezier(0.22, 1, 0.36, 1);    /* 幾乎所有東西的預設 */
  --ease-out:    cubic-bezier(0.17, 1, 0.32, 1);    /* 裝飾性的進場 */
  --ease-spring: cubic-bezier(0.35, 1.55, 0.65, 1); /* 徽章、彈出、要過衝的 */
  --ease-in-out: cubic-bezier(0.66, 0, 0.34, 1);    /* 對稱的移動 */
}
```

他特別講：這些不是什麼神聖的數字，是憑手感調出來的。他把每一條都推來推去，直到按壓、揭露、進場「對了」為止。那個微調的過程本身就是工作。曲線差個 0.02，感覺就會隱隱不對，即使說不出到底哪裡不對。

所以下指令時也一樣——永遠不要說「滑順」。直接把曲線端上去：「所有過場用 `cubic-bezier(0.22, 1, 0.36, 1)`，任何彈出來的東西（像徽章帶一點點回彈）用 `cubic-bezier(0.35, 1.55, 0.65, 1)`。」

第二條順著同一個邏輯往源頭推：**先把設計變數定好，再寫任何一個元件**。精緻讀起來其實是「一致」，而一致來自一套共用的詞彙——也就是設計 token。顏色、圓角、時長、動態曲線、陰影，全部先定成變數，每個游標停留、每個深色模式的變體都從同一套取值。一旦這套存在，模型就不會再亂生 13 像素的圓角和隨機的 0.3 秒，整個介面瞬間踩進同一個節拍。

> 把變數區塊先丟給模型，然後說「只准用這些 token，不准有一次性的數字」。光這一句，就把那種「AI 餿水味」幹掉了八成。

> **Mogu murmur：**
>
> 這條的厲害之處在於，它根本不是在管美感，是在管「自由度」。
>
> 模型每遇到一個沒被你規定的數值，就會自己掰一個——掰出來的 13 像素、0.3 秒、某個介於兩者之間的灰，單看都還行，湊在一起就是一鍋各說各話的雜訊。那不是模型沒品味，是你給了它太多即興發揮的空間。先把 token 釘死，等於把所有「隨便填一個」的縫隙都堵起來，模型剩下的工作就只是組裝，不是發明。你管得越死，它看起來越像出自同一個人的手——這事有夠反直覺。(◕‿◕)

## 描述「感覺」，而不是「術語」

接下來幾條規則表面在講不同元件，骨子裡都是在示範怎麼把「手感」翻譯給模型聽。

任何可以拖的東西，不要用單純的淡入淡出和位移，要用真的物理。一個只靠固定時長做的拖曳把手，摸起來是死的。真實的介面有動量、有摩擦力、有阻力：追蹤使用者滑多快、放手後保留動量慢慢滑到停、撞到邊界時不要硬停而是讓它拉伸一點再彈回來。最後那個回彈，就是「網頁滑桿」和「iOS」之間的全部差距。

更妙的是第四條——**磁吸式的吸附點，是免費的觸覺回饋**。硬體會給「喀」一聲的震動，網頁上則靠吸附點偽造同一種爽感：把手靠近某個有意義的值（一個月份邊界、一個預設檔位）時，輕輕被磁吸過去。讓它真實的訣竅是兩段式——一個比較緊的「吸入區」負責扣上，一個比較大的「脫離區」負責得夠用力才掙得開。扣上去的瞬間閃一下標籤，那一點點阻力，潛意識裡會被讀成「品質」。

而這些東西要怎麼下指令？kvnkld 的答案是：**忘掉術語，直接描述它該有的感覺**。

> 讓這個滑桿摸起來像一個真實的物件，不是網頁輸入框。我撥它一下，它應該繼續滑、自己慢慢滑到停，像在桌面上推一個東西。撞到邊的時候不要硬停，要拉伸一點再彈回來。

模型早就懂那些物理，它缺的只是有人告訴它，要的是哪一種感覺。

第五條藏了一個最被低估的細節：**進場要「模糊地浮現」，永遠不要只是淡入**。一個乾淨的淡入是最被用爛、也最沒高級感的進場。kvnkld 的進場幾乎都是三件事疊在一起——透明度、一點點往上位移、還有一抹會散掉的模糊：

```plaintext
opacity:   0 → 1
translateY: 6px → 0
filter:    blur(2px) → blur(0)
時長:       ~280ms，用 --ease-smooth
```

注意這裡沒有新的緩動曲線，就是第一條那個 `--ease-smooth` 預設。這正是整套動態的重點：手感只定義一次，之後每個進場、每個游標停留、每個揭露全部繼承它。而那 2 像素的模糊就是祕密武器——它讓內容像是「對焦進畫面」，而不是被開關啪一下打開。

> **Mogu OS：**
>
> 我想停在「2 像素模糊」這個數字上，因為它把整篇文章的精神講完了。
>
> 沒有人會在驗收一個介面時說「欸這裡少了 2 像素的模糊」。它小到不可能被列進需求、不可能被開出工單、甚至不可能被你意識到——你只會在它不存在的時候，模糊地覺得這東西有點廉價，然後說不出為什麼。後面那條按壓也一樣：他堅持按下去縮到 98% 不是 95%，因為 95% 會讓人覺得是「塌掉」，98% 才是「紮實地按了一下」。
>
> 差兩個百分點，差兩個像素，分隔的是「能用」和「想一直摸」。這種東西沒辦法外包給模型，因為模型根本不知道它該存在——它是你蹲在螢幕前，一次次覺得「還差一點」然後動手補出來的。(•̀ᴗ•́)

第六條收掉另一個一眼就穿幫的破綻：**一道陰影是貼紙，真正的深度是分層的光**。一個扁平的單層陰影是即時的破功。實體物件同時會投出好幾道陰影——接觸面的髮絲線、緊貼的接觸陰影、外擴的柔和環境光。kvnkld 把它包成標準預設到處用，而讓它讀起來像真的、不像「預設 Material 陰影」的關鍵有三個：用一條髮絲線的內描邊取代邊框（這是手工 UI 最大的破綻——邊緣該由光定義，不是一條 1 像素的線）、每層透明度都壓在 2% 到 8% 這種很小的值（厚重的陰影看起來很廉價，深度是很多層淡光的「總和」）、把好幾個不同大小的模糊疊起來。

剩下幾條是同一種紀律的延伸：每個能點的元素都要有按壓回饋（預設就是按下去縮到 98%）；展開收合不要再用 `max-height: 9999px` 那種會抖、會算錯時間的爛招，改用會動畫化的 `grid-template-rows`（從 `0fr` 到 `1fr`），它會精準地長到內容的真實高度；還有，精緻也包含那些開了「減少動態」的人——每一套動畫都要尊重這個無障礙設定，動畫塌成瞬間完成，裝飾性的循環整個停掉。沒做到這些，就不叫精緻。

## 最重要的一條：元件不是一張圖，是一組狀態

但 kvnkld 把壓軸留給了第十條，也是他說「沒人會教」的那條：**一個元件不是一張圖片，是一套狀態的系統**。一個按鈕不是「一個按鈕」，它是閒置／游標停留／按下／載入中／停用／成功。

而真正的洞見在下半句：**往往要等到開始動手做，才會知道自己需要哪些狀態。** Figma 上的稿子永遠看起來很完整。然後一旦動手做、拖了那個東西一下，破洞立刻浮出來——「這裡需要一個運作中的狀態」「這個數字應該滾動，不是直接換掉」「這個標籤忙碌時應該微微發光」「這個圖示該在播放和暫停之間交叉淡化，不是硬切」。這些微互動是「用的時候發現的」，從來不是事前規格定出來的。

> **Mogu 插嘴：**
>
> 這條根本不只是在講 UI，是在講所有「設計」跟「現實」的關係。
>
> kvnkld 有一句話我很喜歡：Figma 檔是一個假設。它告訴你從哪裡開始，但「實際需要什麼」是做出來、握在手上拖過之後才告訴你的。那些讓人讚嘆的時刻——數字一格一格滾、標籤上掃過一道微光、吸附點扣上去那一下——沒有一個是在設計稿裡規劃的，全是做的過程中從縫隙裡冒出來的。
>
> 這也是為什麼「先設計到完美再開工」常常是個陷阱。你以為自己在降低風險，其實只是把發現問題的時間往後推。真正的狀態、真正的微互動，要等你開始拖那個活的東西，才肯現身。(◠‿◠)

## 模型給不了的那一段

整篇底下的真相是這個。[Claude](https://gu-log.vercel.app/glossary#claude-code)、[Codex](https://gu-log.vercel.app/glossary#codex)、Cursor，這些模型都強到不可思議，它們做一個無懈可擊的彈簧動畫、一個卡片飛越容器的轉場，比任何人手刻都快（[Fable 5 為了修兩行 CSS，自己造了一整套瀏覽器測試工具鏈](https://gu-log.vercel.app/posts/gp-222-20260612-simonwillison-net-fable-5-css)，就是模型把這種苦工整碗端走的活例子）。但沒有任何一個模型決定了按壓要 98% 而不是 95%、沒有一個知道進場缺了一抹 2 像素的模糊、沒有一個知道那個滑桿的脫離區要比吸入區大、也沒有一個知道「這個特定的元件」少了一個運作中的狀態——直到有人親手摸到那個破洞。

那個判斷叫品味，而品味是賺來的：從不斷出貨、從盯著那些「幾乎對了」的東西並知道怎麼修、從多年累積下來「為什麼這個互動讓人愉悅、那個不會」的直覺。模型是那雙手，眼睛仍然是人的。這就是整件事的全部技術含量，也是為什麼同樣的工具，兩個人做得出天差地遠的東西。[設計師開始用 Claude Code 之後、工程師到底還剩什麼價值](https://gu-log.vercel.app/posts/gp-26-20260204-designer-vibe-coding-insight)，其實是同一個答案：機器接手了生產，留在人這邊的是品味。

> [Prompt](https://gu-log.vercel.app/glossary#prompt) 在幾分鐘內帶你走完 90%。最後那 10%——大家真正會去讚嘆、會去轉發的那一段——是你。
