Figma → Landing Page 純 HTML/CSS/JS
此技能可將 Figma 中的 Landing Page 設計稿轉換為靜態 HTML、CSS 和 JS 頁面。 工作方式是逐區塊進行:每完成一個區塊,代理會暫停並等待用戶確認。
排版規則(結構、BEM 命名、單位、圖片、懸停效果等)均詳列於此技能的 templates/AGENTS.md。在步驟 3 中,該檔案會被複製到專案根目錄,並在後續步驟中持續生效。
要求
- 需已連線 Figma MCP(
get_metadata、get_design_context、get_screenshot,若有則也使用get_variable_defs)。若未連線,請告知用戶並停止。 - 用戶需提供類似
https://www.figma.com/design/:fileKey/:fileName?node-id=1-2的連結。 - 伺服器、螢幕截圖與 WebP 轉換需要 Node.js。首次執行
npx指令時會從網路下載套件——Codex 可能會要求授權,這是正常現象。
工作流程
請依序執行以下步驟,不可跳過。
步驟 1:解析連結
fileKey:為/design/之後的部分。若連結中包含/branch/:branchKey/,則使用branchKey。nodeId:為node-id的值,將連字號替換為冒號(例如1-2→1:2)。- 連結可能指向整個文件、單一頁面、桌面框架或行動框架。類型將於步驟 2 中判斷。
步驟 2:設計稿地圖
- 針對連結中的節點呼叫
get_metadata(若為整個文件,則不使用node-id或使用根頁面)。 - 找出 Landing Page 的各版本框架:桌面版、行動版,有時還有平板版。寬度需從設計稿中確定,不可使用預設值。同時找出頁面上獨立存在的模態視窗(彈窗)框架及展開的行動選單框架(若有)。
- 在每個框架內,標出頂層區段(頁首、Hero、優勢、評論、頁尾等)。
- 比對各版本間的區段:「桌面區段 ↔ 行動區段」(依據圖層名稱、順序與內容)。
- 向用戶呈現地圖並等待確認:
寬度:桌面 1440,行動 375
1. header — 12:30 ↔ 40:2
2. hero — 12:45 ↔ 40:18
3. advantages — 13:10 ↔ 41:5
...
模態視窗 / 選單:
- mobile-menu — 45:12
- popup-order — 46:01
若無行動版,請告知用戶並詢問後續處理方式。
步驟 3:專案骨架與基礎 UI
- 若專案根目錄中尚無
AGENTS.md,則從技能資料夾複製templates/AGENTS.md。根據步驟 2 的資料,填入「此 Landing Page」區段(寬度、容器、字型)。斷點保留預設值;僅在當前設計稿在其他寬度下排版異常時才修改,並記錄新的斷點。 - 建立目錄結構:
index.html、style.css、script.js、assets/icons/。 index.html:設定<!doctype html>、lang="zh-TW"、charset、viewport、<title>及<meta name="description">(依據 Landing Page 的內容)。不加入 favicon。使用defer載入script.js。- 字型:從
get_design_context/get_variable_defs取得,僅透過 Google Fonts 載入需要的字重,並使用display=swap。若 Google Fonts 中無此字型,請向用戶索取字型檔案,並透過@font-face從assets/fonts/引入。 style.css:重置樣式(參見AGENTS.md),接著是:root,其中包含顏色、字型、間距、容器寬度等變數。若設計稿中有變數,則從get_variable_defs取值;否則從設計稿中提取並四捨五入。- 基礎元件: 將設計稿中的通用元素(按鈕、區段標題、輸入框)提取為可複用類別(
.btn、.section-title、.input、.container)。若設計稿中無包含狀態(hover、focus、active)的 UI 庫,僅一次詢問用戶典型按鈕與連結的懸停規則,並套用至整個專案。將答案記錄在AGENTS.md中「此 Landing Page」區段的「UI 狀態」一行。 - 工具(僅一次):
- 在背景啟動專案根目錄的本地伺服器:
npx -y serve -l 3000(備用方案:python3 -m http.server 3000)。所有螢幕截圖應從http://localhost:3000取得,不可使用file://。 - 確認截圖工具:若已連線 Playwright MCP 則使用之;否則使用
scripts/shot.cjs腳本(參見「自我檢查」)。 - 確認圖片轉換工具(參見「圖片」)並記下結果。
- 在背景啟動專案根目錄的本地伺服器:
- 通知用戶骨架已完成,並開始第一個區塊。
步驟 4:逐區塊處理
針對地圖中的每個區段,嚴格依序從上到下進行(包含表單區段):
- 資料。 對桌面區段及其行動版配對,呼叫
get_design_context與get_screenshot。- 若回應被截斷或過大——對該區段使用
get_metadata,並逐一取得子節點。 - 回應中的程式碼(通常為 React + Tailwind)僅作尺寸、顏色與結構的參考。不可複製其樣式。
- 若回應被截斷或過大——對該區段使用
- 圖片。 下載並處理該區塊的資源(參見「圖片」)。
- 排版。 在
index.html中新增區塊的 HTML,在style.css中以註解/* ===== hero ===== */分隔的新區段撰寫樣式,必要時在script.js中撰寫 JavaScript。使用步驟 3.6 建立的基礎類別,避免重複按鈕與標題的程式碼。先寫桌面版,再透過clamp()與 media query 實現響應式至行動版。- 對於
header,在行動版寬度下立即實作漢堡選單(依據地圖中的框架或詢問用戶確認外觀)。 - 若區塊包含表單——使用瀏覽器原生驗證屬性(
required、type="email"、type="tel"、pattern)進行排版,但暫不加入 JavaScript 提交邏輯。
- 對於
- 自我檢查。 在桌面版、行動版及中間寬度(1024、768)下僅對目前區段進行螢幕截圖。與 Figma 截圖比對:間距、尺寸、字型、顏色、換行。修正發現的問題並重新截圖。
- 若使用 Playwright MCP——對每個寬度下的區段元素進行截圖。
- 若無 MCP——使用技能資料夾中的腳本:
腳本會將截圖儲存為# 僅一次 mkdir -p .screens && cp <技能資料夾>/scripts/shot.cjs .screens/ npm i playwright --prefix .screens && npx -y playwright install chromium # 每個區塊完成後 node .screens/shot.cjs http://localhost:3000 .hero 1440,1024,768,375.screens/<區段>-<寬度>.png,若頁面超出螢幕寬度則輸出⚠ 水平捲動警告。任何此類警告都應修正原因(不可使用overflow: hidden在body上隱藏)。 - 區塊確認後刪除其截圖;腳本與
.screens/中的node_modules則保留至步驟 6。
- 報告與暫停。 簡短告知用戶:已完成項目、與設計稿的差異及原因、需確認的獨特互動元素(例如非標準卡片懸停效果、滑塊參數)。等待確認。 用戶提出的修改在同一區塊內進行,之後再次等待。
- 僅在收到「完成」回覆後,才繼續下一個區塊。
步驟 5:模態視窗與表單邏輯
完成所有主要區段的排版後:
- 排版步驟 2 中找到的隱藏模態視窗(彈窗),並加入開關觸發條件(按鈕、
Esc鍵、點擊遮罩層)。行為請參考AGENTS.md中的「JavaScript」區段。 - 每個視窗視為獨立區塊: 在開啟狀態下進行螢幕截圖自我檢查,然後報告並等待確認。
- 檢查頁面上所有表單的功能。在用戶主動要求並提供端點或規格之前,不要傳送任何資料(
fetch/AJAX)。
步驟 6:最終處理
最後一個階段確認後:檢查整個頁面在所有寬度下的顯示效果,刪除暫存檔案與資料夾(assets/_raw/、.screens/ 整個刪除),停止背景執行的本地伺服器,移除未使用的樣式與圖片。撰寫簡短總結。
圖片
- 區塊的資源從 Figma MCP 的回應中取得(
get_design_context中的圖片連結)。若返回localhost位址,則直接下載。不使用佔位圖或第三方圖示集。 - 下載至暫存目錄
assets/_raw/<區塊>/,點陣圖尺寸為設計稿中的 2 倍(2x)。 - 響應式圖片: 若行動版區塊使用裁切(不同比例)或意義不同的圖片,則下載兩個版本(例如
hero-bg-desktop.webp與hero-bg-mobile.webp)並透過<picture>引入。 - 分類:
- 互動元素(按鈕、連結)內的小圖示,需在懸停時變色(
fill/stroke)→ 使用內聯<svg>搭配fill="currentColor"(或透過 CSSmask-image); - 靜態圖示、標誌、簡單圖形 → 以
<img>方式存放於assets/icons/(若為大圖則放入區塊資料夾)。若圖示為點陣圖,請告知用戶; - 照片與複雜圖片 → 轉換為 WebP 格式,存放於
assets/<區塊>/。
- 互動元素(按鈕、連結)內的小圖示,需在懸停時變色(
- 轉換為 WebP,品質 80。嘗試順序:
npx -y sharp-cli -i in.png -o out.webp -f webp -q 80(需要 Node.js);cwebp -q 80 in.png -o out.webp;- 若以上皆無——保留原始格式,並僅一次告知用戶需安裝(Node.js 或
cwebp),不中斷工作。
- 若 WebP 檔案比原始檔更大——保留原始格式。
- 檔案命名:拉丁字母、小寫、連字號分隔、意義明確(例如
hero-photo.webp、arrow-right.svg)。 - 區塊確認後,刪除
assets/_raw/<區塊>/。
懸停效果、動畫、滑塊
- 懸停效果: 基本按鈕與連結遵循
AGENTS.md中「UI 狀態」行的規則。若區塊中有獨特的互動卡片/元素,且設計稿中未定義狀態——不要自行猜測,而是在該區塊的報告中詢問用戶。 - 滾動動畫與自訂動畫: 僅在用戶主動要求時才加入。先釐清具體效果。簡單效果(滾動時淡入)使用
IntersectionObserver;複雜效果(綁定滾輪、黏性區段、視差)則透過 CDN 載入 GSAP,且需經用戶同意。務必考慮prefers-reduced-motion。 - 滑塊: 簡單滑塊(箭頭、圓點、滑動)使用自訂 CSS
scroll-snap搭配少量 JavaScript。複雜滑塊(無限循環、自動播放、特效、連動滑塊)則透過 CDN 載入 Swiper。
常見問題
- Figma 回應被截斷 → 對區段使用
get_metadata,再對子節點使用get_design_context。 - 找不到區段的行動版配對或行動選單框架 → 詢問用戶,不可自行猜測。
- 字型寬度與設計稿不符 → 檢查字重與
letter-spacing,勿調整字型大小。 - 圖片無法下載 → 確認 Figma MCP 正在執行;直接使用回傳的連結,不做修改。
- 螢幕截圖中字型或圖示遺失 → 確認伺服器在
localhost:3000上執行,且截圖來自該伺服器而非file://。 - 腳本顯示「水平捲動」 → 找出寬度超出螢幕的元素(固定寬度、過大的
gap、超出邊緣的裝飾元素)並修正;對於超出邊緣的裝飾元素,可在其區段使用overflow-x: clip。 - 因無障礙或技術限制而偏離設計稿 → 可接受,但需在該區塊的報告中提及。