懶人包
- apple-design 是 Emil Kowalski 開源的 AI agent skill,收在
emilkowalski/skills這個 repo 裡(MIT),把 Apple WWDC 設計演講的動效與介面原則改寫成 17 節「給網頁用」的規範,2026-07-09 加入 repo。- 熱度是真的:repo 在 2026-10-20 是 47.8k stars、2.8k forks。但這是整個 repo 15 支 skill 共用的數字,不是 apple-design 一支的。
- 我用同一句需求讓 Claude Code(Sonnet)寫一個「往下拖曳關閉」的 bottom sheet:有用上 skill 的版本多了彈簧物理、放手速度銜接、Apple 的動量投射公式與橡皮筋邊界;沒用上的版本是 CSS transition 加距離門檻。
- 坑:裝了不保證會被用上。同一句需求、沒點名 skill 的情況我跑了 3 次,只有 1 次自動觸發;在需求前面加
/apple-design那次直接用上。想要穩定效果就點名。
- apple-design skill 是什麼?
- 作者是誰、到底多紅?
- 17 節在講什麼?
- 怎麼安裝到 Claude Code?
- 實測:同一個 bottom sheet,有沒有用上它差在哪
- 踩坑:裝了不等於會被用上
- 拿它改我自己的部落格,改了哪些?
- 跟 dickwu/apple-design-skill 怎麼選?
- 什麼情況不適合用
- 延伸資源
🍎 apple-design skill 是什麼?
apple-design 是一份給 AI coding agent 讀的 SKILL.md,290 行。它的定位寫在開頭:把 Apple 讓介面「不再像一台電腦、而像身體延伸」的做法,翻譯成網頁平台上的實作——CSS、Pointer Events、requestAnimationFrame,以及 Motion/Framer Motion 這類 spring 函式庫。
內容來源是 Apple 的 WWDC 設計演講,主軸是 *Designing Fluid Interfaces*(WWDC 2018),另外引用了 *Designing Audio-Haptic Experiences*、*The Details of UI Typography*(WWDC 2020)和 *Principles of Great Design*(WWDC 2026)。
它不是 iOS/SwiftUI 的開發指南,也不是 Human Interface Guidelines 的檢查清單。它解決的問題很具體:AI 寫出來的拖曳、彈出、關閉動畫常常是「一條固定時間的 ease 曲線」,能動,但手感不像原生 App。這份 skill 把「為什麼原生 App 手感好」拆成一條條可以寫進程式的規則和公式。
👤 作者是誰、到底多紅?
作者 Emil Kowalski 的個人網站寫著他目前在 Linear 的 Web team,之前在 Vercel 的設計團隊。前端圈對他比較熟的作品是 toast 元件 sonner 和 drawer 元件 vaul。repo README 說這些 skill 是根據他在 Vercel、Linear 這類公司工作多年的經驗整理的。
網路上流傳的介紹有幾處跟一手資料對不上,我逐項查了 GitHub API 和作者網站:
| 說法 | 一手資料(2026-10-20 查) |
|---|---|
| 「前 Vercel / Linear 設計工程師」 | 個人網站:目前在 Linear Web team,之前在 Vercel 設計團隊 |
| 「GitHub 破萬星」 | emilkowalski/skills 是 47,831 stars、2,762 forks,但這是整個 repo 的數字 |
| 「apple-design 一支 skill 的星數」 | GitHub 只能對 repo 加星,無法拆到單一 skill |
| 「把 17 條原則濃縮自 Designing Fluid Interfaces」 | 17 節中,主軸來自這場,但字體、多感官回饋、八大原則來自另外三場演講 |
| 推出時間 | repo 建立於 2026-03-16;apple-design 在 2026-07-09 加入 |
📚 17 節在講什麼?
我把 SKILL.md 的 17 節依用途分成五組,每節後面列它給的具體規則或數值:
| 分組 | 節次與重點 |
|---|---|
| 回應與跟手 | 1 Response:消滅延遲;2 Direct manipulation:手指移多少、元素就移多少;3 Interruptibility:任何動畫都要能被半途抓住,作者標為最重要的一條 |
| 物理動態 | 4 用 spring 取代固定時間曲線,以 damping ratio + response 描述,附 Apple 的參考值(一般移動 1.0/0.4、旋轉 0.8/0.4、抽屜 0.8/0.3);5 Velocity handoff:放手時把手勢速度交給 spring;6 Momentum projection:依放手速度推算元素「要去哪」,公式 (v/1000)*d/(1-d),d 約 0.998 |
| 空間與手勢 | 7 空間一致性:從哪出現就回哪去;8 動畫方向提示手勢方向;9 Rubber-banding:超出邊界時阻力遞增,公式 (overshoot*dimension*c)/(dimension+c*|overshoot|),c = 0.55;10 手勢細節檢查表;11 逐幀流暢度 |
| 材質與感官 | 12 半透明材質(backdrop-filter)表達層級;13 動作、聲音、觸覺三者的因果、和諧、實用;14 prefers-reduced-motion、prefers-reduced-transparency、prefers-contrast |
| 字體與原則 | 15 字體:光學尺寸、字距、行高;16 Apple 八大設計原則:Purpose、Agency、Responsibility、Familiarity、Flexibility、Simplicity、Craft、Delight;17 工作流程 |
⚙️ 怎麼安裝到 Claude Code?
README 給的是一次裝整個 repo 的指令,會進入互動式選單:
npx skills@latest add emilkowalski/skills
只想要 apple-design 一支、而且裝給 Claude Code,我實際跑過的是這條(鎖定 skills CLI 1.7.4 版,--copy 是複製檔案而非建 symlink,-y 跳過確認):
npx -y skills@1.7.4 add emilkowalski/skills --skill apple-design --agent claude-code --copy -y
跑完後專案裡會多出 .claude/skills/apple-design/SKILL.md 和一份 skills-lock.json。安裝過程 CLI 會顯示第三方安全評估,我那次三項都是低風險(Gen Safe、Socket 0 alerts、Snyk Low Risk)。
驗證有沒有裝好:開一個新的 Claude Code session,輸入 / 看清單裡有沒有 apple-design。我是用 --output-format stream-json 跑,session 初始化那一行的 skills 清單會列出它。
🧪 實測:同一個 bottom sheet,有沒有用上它差在哪
我開了幾個乾淨的資料夾,用同一句需求叫 Claude Code 寫檔,模型都是 Sonnet,Claude Code 版本 2.1.304:
在目前資料夾建立單一檔案 sheet.html:一個可以用手指或滑鼠「往下拖曳關閉」的
bottom sheet,頁面上有一顆按鈕可以打開它。只用原生 HTML/CSS/JS,不要裝套件、
不要用 CDN。寫完檔案就結束,不用解釋。
對照組資料夾沒裝 skill;實驗組在需求最前面加上 /apple-design。兩份產出的寫法差異如下:
| 項目 | 沒用 skill | 點名 /apple-design |
|---|---|---|
| 檔案長度 | 206 行 | 401 行 |
| 放手後怎麼動 | CSS transition,0.3 秒固定曲線 | 自寫 spring(damping + response),用 requestAnimationFrame 逐幀算 |
| 放手速度 | 只看最後一次移動的瞬間速度,超過門檻就關 | 取最近 100ms 的取樣算速度,傳給 spring 當初速 |
| 要不要關閉 | 拖超過高度 30% 或速度夠快 | 用 Apple 動量投射公式算「放手後會停在哪」,超過一半才關 |
| 往上拉超過頂端 | 直接卡住(Math.max(0, …)) | 橡皮筋阻力,c = 0.55 |
| 動畫中途抓住 | 沒有特別處理 | pointerdown 時取消動畫、從當下位置接手 |
| 減少動態偏好 | 沒有 | 偵測 prefers-reduced-motion,直接到位不播動畫 |
| 材質 | 白底 | backdrop-filter 半透明,背景頁面縮小加圓角 |
實驗組產出的程式碼裡,動量投射和橡皮筋就是照 skill 第 6、9 節的公式寫的:
const DECELERATION = 0.998;
const project = (v, d = DECELERATION) => (v / 1000) * d / (1 - d);
const rubberband = (over, dim, c = 0.55) =>
(over * dim * c) / (dim + c * Math.abs(over));
這段是這次實驗最直接的證據:0.998 和 0.55 這兩個數字,對照組的程式碼裡完全沒出現。
🕳️ 踩坑:裝了不等於會被用上
這是我這次最在意的發現。Claude Code 會在 session 開始時把每支 skill 的 description 列給模型看,由模型自己判斷要不要載入。apple-design 的 description 明確寫了 drag/swipe/sheet interactions,看起來應該會被我的需求觸發。
實際結果:同一句需求(沒有點名),在裝了 skill 的乾淨資料夾跑了 3 次。
| 次數 | 有沒有呼叫 Skill 工具 | 產出 |
|---|---|---|
| 第 1 次 | 沒有 | CSS transition 加速度門檻,跟對照組同一層級 |
| 第 2 次 | 沒有 | 同上,有加 prefers-reduced-motion |
| 第 3 次 | 有,載入 apple-design | 出現 spring、0.998 動量投射、橡皮筋 |
點名 /apple-design | 有 | 見上一節 |
我的做法:
- 要寫手勢、拖曳、彈出類的互動時,在需求前面直接打
/apple-design。 - 或是在需求裡寫「依照 apple-design skill」,讓模型不用猜。
- 驗收時翻一下產出:有沒有 spring、有沒有速度銜接,比看 log 更快知道 skill 有沒有生效。
🛠️ 拿它改我自己的部落格,改了哪些?
實驗之後,我在 2026-10-21 照這份 skill 把這個部落格本身的互動細節改了一輪(commit 07d7267,改了 4 個檔案、新增 143 行),當天部署上線。每一項都對得到 skill 的某一節:
| 改了什麼 | 原本 | 現在 | 對應章節 |
|---|---|---|---|
| 卡片按下 | 只有滑鼠 hover 才會抬起,手機上點下去沒有回饋 | 按下瞬間就壓進陰影(:active,80ms);hover 抬起只在滑鼠裝置生效 | §1 Response |
| 文章目錄箭頭 | 有 .toc-caret 這個 class 卻沒寫樣式,開合時箭頭不動 | 展開轉 180°、收合轉回 | §8 動畫方向提示結果 |
| 分類/標籤/搜尋篩選 | 不符合的卡片直接消失 | 往下淡出、符合的從下方淡入;途中改條件會從當下的透明度接著跑,不會跳 | §3 可中斷、§7 進出同一路徑 |
| 手機選單 | 高度 100vh,底部被瀏覽器網址列蓋住 | 改用 dvh;從右上漢堡鈕展開,關閉時沿原路收回 | §7 空間一致性 |
| 減少動態偏好 | 所有過場一律 0.01ms,等於整站沒有回饋 | 位移與縮放拿掉,顏色與透明度保留 150ms 淡入淡出 | §14 Reduced motion |
| 手機輸入框 | 搜尋框 12px,iPhone 一點就整頁放大 | 觸控裝置(pointer: coarse)所有輸入框至少 16px,會員登入、留言板一併涵蓋 | §15 字體、§16 Craft |
| 瀏海與底部安全區 | 沒有設定 | viewport-fit=cover、底部導覽補 env(safe-area-inset-bottom)、加 theme-color | §16 Flexibility |
transition-duration 壓到 0.01ms,暈動症使用者不會被位移干擾,但「按了有反應」的回饋也一起沒了。skill 第 14 節的說法是減少動態不等於沒有回饋,要換成溫和、不引起前庭不適的版本,所以這次只關位移和縮放。
改完我用 curl 抓 production 的 HTML 和 CSS 確認 viewport-fit=cover、pointer:coarse、.lift:active、dvh、safe-area-inset-bottom 都在線上版本裡。iPhone 實機上的放大與安全區遮擋,我沒有在實機上逐項驗證。
其中目錄箭頭和篩選動畫是同 repo 的 find-animation-opportunities 先挑出來的,輸入框放大、dvh 和安全區是 mobile-native 找到的,那兩篇有更完整的修前修後。
⚖️ 跟 dickwu/apple-design-skill 怎麼選?
搜尋 apple design skill 時,另一個常出現的是 dickwu/apple-design-skill(2026-10-20 是 1,669 stars、136 forks)。兩者名字像,方向不同:
| 比較 | emilkowalski 的 apple-design | dickwu/apple-design-skill |
|---|---|---|
| 主軸 | WWDC 演講中的動效、手勢、材質原則 | Apple Human Interface Guidelines 檢查 |
| 平台 | 網頁(CSS、Pointer Events、Motion) | 跨平台,README 提到 Flutter、Tauri、Electron、React Native |
| 最適合的情境 | 寫出有原生手感的互動元件 | 審查介面是否符合 HIG 規範 |
| 授權 | MIT | repo 未標示 license |
| skill 名稱 | apple-design | 也是 apple-design |
SKILL.md 都宣告 name: apple-design,裝進同一個 .claude/skills/ 會撞名,擇一安裝比較單純。GitHub 上另外還有 naplesblue/apple-design-skill(276 stars)等同名 repo,其餘都在 30 stars 以下,我沒有實測。
🚧 什麼情況不適合用
- 寫原生 iOS/SwiftUI:這份 skill 明確是「翻譯給網頁」的版本,範例都是 CSS 和 JS。同 repo 有
write-swift和mobile-native兩支,原生開發看那兩支比較對。 - 後台表格、表單為主的系統:17 節裡大部分是手勢與動態,對「列表加查詢加編輯」的頁面幫助有限。這類頁面我會只取第 1 節的回應速度和第 14 節的無障礙偏好。
- 已經在用 vaul 或 Motion 的專案:現成函式庫已經處理好 spring 和速度銜接,這時候 skill 的價值是「讓 AI 正確設定參數」,不是讓它從零手刻。我這次限制只用原生 JS,所以 AI 自己寫了 spring 積分器,在真實專案裡我會讓它用函式庫。
- 在意程式碼長度:實驗組 401 行,是對照組的兩倍左右。多出來的都是物理計算和無障礙處理,手感值得,但要準備好維護這些程式碼。
🔗 延伸資源
- GitHub repo:emilkowalski/skills
- skill 原文:skills/apple-design/SKILL.md
- 作者網站:emilkowal.ski
- 跨平台 HIG 審查:dickwu/apple-design-skill
- 想看我自己怎麼把工作流寫成 skill:8 支 Claude Code 旗艦 skill:從開案到發文一條龍
/apple-design 請 Claude Code 依第 3、5、9 節重寫一次,打開手機實際拖拖看。手感差異用手指比用眼睛更容易分辨。