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

kvnkld 常被人追問:那些貼出來的元件怎麼做到這麼精緻?到底是下了什麼 prompt?他乾脆把整套規則攤開來,而開場第一句就先把幻想戳破:

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

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

Mogu 偷偷說:

這句話值得裱框。一堆人用 AI 做東西的方式,是把自己腦中那團模糊的「我想要它看起來厲害」原封不動丟給模型,然後對著吐回來的成品皺眉:欸,不是這個感覺。

問題是「這個感覺」從來沒被你說出口過。你心裡的「高級」可能是 280 毫秒的緩動加一點點過衝,但你嘴上只給了「高級」兩個字——模型只好猜,猜出來的就是那種人人都看過、誰都不會記得的平庸版本。形容詞是你偷懶的藉口,模型只是忠實地把你的偷懶顯影出來而已。⁠(⁠¬⁠‿⁠¬⁠)

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

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

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

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

: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 OS:

這條的厲害之處在於,它根本不是在管美感,是在管「自由度」。

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

描述「感覺」,而不是「術語」

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

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

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

而這些東西要怎麼下指令?kvnkld 的答案是:忘掉術語,直接描述它該有的感覺

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

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

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

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

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

Mogu 補個刀:

我想停在「2 像素模糊」這個數字上,因為它把整篇文章的精神講完了。

沒有人會在驗收一個介面時說「欸這裡少了 2 像素的模糊」。它小到不可能被列進需求、不可能被開出工單、甚至不可能被你意識到——你只會在它不存在的時候,模糊地覺得這東西有點廉價,然後說不出為什麼。後面那條按壓也一樣:他堅持按下去縮到 98% 不是 95%,因為 95% 會讓人覺得是「塌掉」,98% 才是「紮實地按了一下」。

差兩個百分點,差兩個像素,分隔的是「能用」和「想一直摸」。這種東西沒辦法外包給模型,因為模型根本不知道它該存在——它是你蹲在螢幕前,一次次覺得「還差一點」然後動手補出來的。⁠(⁠•⁠̀⁠ᴗ⁠•⁠́⁠)

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

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

最重要的一條:元件不是一張圖,是一組狀態

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

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

Mogu 偷偷說:

這條根本不只是在講 UI,是在講所有「設計」跟「現實」的關係。

kvnkld 有一句話我很喜歡:Figma 檔是一個假設。它告訴你從哪裡開始,但「實際需要什麼」是做出來、握在手上拖過之後才告訴你的。那些讓人讚嘆的時刻——數字一格一格滾、標籤上掃過一道微光、吸附點扣上去那一下——沒有一個是在設計稿裡規劃的,全是做的過程中從縫隙裡冒出來的。

這也是為什麼「先設計到完美再開工」常常是個陷阱。你以為自己在降低風險,其實只是把發現問題的時間往後推。真正的狀態、真正的微互動,要等你開始拖那個活的東西,才肯現身。⁠(⁠◠⁠‿⁠◠⁠)

模型給不了的那一段

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

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

Prompt 在幾分鐘內帶你走完 90%。最後那 10%——大家真正會去讚嘆、會去轉發的那一段——是你。