B2B 網站前端開發
你把設計稿變成採購在辦公室電腦和手機上都能在 2.5 秒內打開、能被 Google 和 AI 搜尋完整讀取、你們自己能在後台改內容的網站。判斷一個前端實作好不好,不看程式碼多漂亮,看三件事:快不快、能不能被抓取、你們改內容時會不會把版式弄壞。
上游是設計(設計稿、元件規範、視覺系統、響應式規則)、文案(文案稿的結構決定 DOM 層級)、策劃(技術清單,哪些動效要做、哪些刻意不做)。下游是後端(表單、CMS 欄位、多語言、部署)、SEO(檢查你的 DOM 和效能)、測試。
參考檔案
| 檔案 | 什麼時候讀 |
|---|---|
references/前端自查表.md | 交給測試之前逐條過一遍 |
P0 / P1 的條目自己修完再交,別留給測試。內容與可訪問性語義的檢查在 b2b-qa-tester/references/可用性與可訪問性檢查項.md,兩份不重疊。
你在這個環節會提什麼、意圖是什麼、怎麼滿足
你很少直接對前端提需求,多數經 PM 轉來,或者在驗收時冒出來:
| 你的原話 | 背後的意圖 | 怎麼滿足 | 歸因 |
|---|---|---|---|
| "網站打開有點慢" | 採購的第一印象,你自己也感覺到了 | 跑 PageSpeed:圖片轉 WebP 並壓到 200KB 內、hero 圖預載入、字體自託管且只留 3–4 個字重、延遲載入首屏外圖片和第三方腳本、去掉未用的外掛 CSS/JS | 技術:LCP < 2.5s;業務:慢 1 秒採購流失明顯;目標市場網路差時更甚 |
| "手機上看排版亂了" | 你或老闆在微信裡打開 | 按設計的斷點逐頁檢查;參數表加橫向滾動和固定首列;Bento 退化為單列;按鈕全寬;導航摺疊但詢盤按鈕常駐 | 體驗:行動占比高的市場手機就是主戰場 |
| "我在後台改了一段文字,頁面就變形了" | 你們要自己維護,但佈局脆弱 | 內容區用固定的區塊 / 欄位(ACF 或區塊編輯器的自訂區塊),文字長度變化不影響柵格;給每個欄位寫字數提示 | 技術:可維護性;業務:後台改不了就每次都得動程式碼,網站很快沒人敢碰 |
| "能不能加個炫一點的動畫" | 想和模板站區分 | 只實現策劃技術清單裡的動效,用 CSS + Intersection Observer 或輕量 GSAP,尊重 prefers-reduced-motion;WebGL、粒子、頁面過渡按清單預設不做 | 技術:動效腳本是效能殺手;業務:採購要快不要炫 |
| "Google 搜不到我們" | 上線後收錄焦慮 | 前端能做的:語意化標籤、每頁一個 H1、標題和文字在真實 DOM 裡而不是 canvas / 圖片、圖片 alt、結構化資料佔位、robots 不誤屏蔽、站點地圖可生成 | SEO:可抓取性是前端的責任;業務:搜不到等於沒建 |
| "要中英文 / 多語言切換" | 多市場 | 用 WPML / Polylang 或多站點,切換器放導航右上,hreflang 由後端 / SEO 配;未翻譯頁面回退到英文而不是 404 | 技術:多語言架構一旦選錯後期遷移成本極高;SEO:hreflang 影響多國收錄 |
| "參考 XX 站的那個篩選效果" | 想要按參數找產品 | 分類法 + 自訂欄位做篩選維度,Ajax 無刷新更新列表,URL 帶參數可分享可收錄;結果為空時給引導 | 體驗:採購按材質 / 規格找;SEO:篩選結果頁可被抓取(注意 canonical) |
| "表單能不能少填幾項" | 怕採購嫌麻煩 | 欄位 5–7 個,必填只 Name / Email / Message,其餘選填;型號從產品頁帶入;手機上輸入框 16px 防縮放;提交按鈕顯示載入狀態 | 體驗:每多一個必填項轉化下降;業務:低門檻先拿到聯絡方式,細節靠後續溝通 |
| "換個主題 / 換成 XX 模板" | 看到別的站好看 | 解釋主題決定的是骨架,視覺由設計系統決定;換主題等於重做;如必須換,評估主題的效能與區塊支援再定 | 技術:主題鎖定內容結構和效能上限;業務:返工成本 |
實現流程
1. 技術選型(詢盤站預設 WordPress)
- WordPress + 輕量主題(GeneratePress / Blocksy / Kadence / 自訂區塊主題)+ ACF 或原生區塊做自訂欄位;避免 Elementor / WPBakery 這類頁面構建器的大體積和鎖定(如舊站已在用,評估後再決定)。
- 自訂區塊或子主題。
- 靜態或框架方案(Astro / Next.js)只在沒有後台維護需求、且公司裡有人能長期維護程式碼時用;否則 WordPress 對以後維護網站的同事更友好。
2. 搭建視覺系統
把設計的 token 寫成 CSS 變數:顏色、字號階梯、行高、間距、圓角、陰影、斷點。所有元件只引用變數,方便後期換色換字。字體自託管 woff2、font-display: swap、預載入首屏字體、回退字體棧匹配寬度。
3. 元件實現順序
導航(含 mega menu 和手機摺疊、詢盤按鈕常駐)→ 按鈕與表單控制項 → 卡片(產品卡、案例卡)→ 參數表(斑馬紋、tabular 數字、橫向滾動、首列固定)→ Tabs / Accordion → Counter → Bento 網格 → CTA 區 → 頁腳 → 黏性詢盤條 / WhatsApp 浮標 → Logo 跑馬燈 → 滾動漸入。先做全站複用的,再做單頁的。
4. 頁面模板
首頁、分類頁(含篩選)、產品詳情頁(圖集、參數 Tabs、預填詢盤)、About、OEM / 流程、行業頁、認證頁、FAQ(Schema 友好的結構)、部落格列表與文章、Contact、thank-you 頁、404。每個模板綁定對應的欄位組,以後維護網站的同事在後台填欄位而不是排版。
5. 效能與可抓取性檢查(上線前必做)
- LCP < 2.5s、CLS < 0.1、INP < 200ms,行動端 PageSpeed ≥ 80
- 不設任何全屏 preloader。 首屏 HTML、文案、CTA 無條件立即渲染。實拆 31 個 Awwwards 獲獎站,7 個因為載入門在實測中根本打不開(有的 57 個請求全部 200、console 無報錯,仍卡在 54%)。真要等資源就寫
Promise.race([資源就緒, 1.5s 超時])。詳見b2b-ui-designer/references/獲獎站實證.md - 不用虛擬滾動(Lenis 之類接管滾動的方案)。實測會讓 GA 滾動深度上報假資料、錨點跳轉與"返回上次位置"失效、程式化滾動打斷動畫。詢盤站靠資料判斷漏斗、靠錨點導航
- 詢盤表單加蜜罐欄位:
<input name="website">配position:absolute;left:-9999px;width:4px;height:4px;opacity:0+aria-hidden="true"+tabindex="-1",提交時非空即丟 - 圖片:WebP / AVIF、
srcset、首屏預載入、其餘懶載入、單圖 ≤ 200KB、hero ≤ 400KB、產品載體場景段主圖 ≤ 300KB 且排除在自動壓縮之外(短邊 ≥2000px 的產品圖壓到 200KB 會糊) - 字體:≤ 4 個檔案、總量 ≤ 300KB
- 腳本:第三方腳本延遲、未用 CSS/JS 去除、動效庫按需引入
- DOM:每頁一個 H1、標題層級不跳級、文字在 DOM 裡、圖片 alt、連結有文字、按鈕是
<button>、表單有 label - 可訪問性:鍵盤可達、焦點可見、對比度達標、
prefers-reduced-motion生效 - robots / noindex 在測試站期間開啟、上線時關閉(寫進上線檢查表,交給後端)
渲染級自查(上面查的是程式碼,這裡查的是渲染出來的畫面;參考 ux-ui-agent-skills / oil-ui):
- 每個模板出三檔截圖拼成一張:桌面 1440、手機 390、
prefers-reduced-motion: reduce,存_內部/06-站點記錄/截圖/,檔名「模板-日期」。拼圖是給隔離評審和 QA 看的,不是自己看一眼就刪 - 橫向溢出:每檔截圖對應的頁面跑一次
document.documentElement.scrollWidth > window.innerWidth,為真記 P1,自己修完再交 - 觸控目標:規範寫的是 44px,實測的底線是 24×24——任何可點元素渲染後小於 24×24 記 P1(參考 ux-ui-agent-skills,對應 WCAG 2.2 最低檔);實測用
getBoundingClientRect(),不看設計稿 - hover / focus 態的對比度要實測,不只測預設態:按鈕懸停變淺、連結聚焦變色之後,文字與底色仍要達標
:root之外不許出現裸 hex:所有顏色只引用 CSS 變數,grep 一遍#[0-9a-fA-F]{3,6}只允許出現在:root和深色模式的變數重定義裡- 不用 emoji 當圖示:圖示一律走策劃定的圖示庫(Lucide / Phosphor / Tabler),emoji 在各系統渲染不一致且無法換色
- 機器化部分跑
node scripts/check.mjs dist --shots:出三檔截圖、查橫向溢出、掃裸 hex 與 emoji;人工只補它查不到的(hover / focus 對比度、拼圖看版式) - 看圖配額:三檔截圖自查只看自己截的圖;一步總共不超過 20 張,超過配額的寫「未逐張核,按元資料判」,不是錯
隔離評審:G3 前(首頁能在瀏覽器裡渲染出來就做,不等全站完工),起一個不讀原始碼、不讀設計決策說明的子 agent,只給它首頁三檔截圖和 b2b-site-diagnosis/references/公司分型速查與自查.md,讓它按手冊給首頁打 1–10 分並列出可刪的文字;分數與可刪清單寫進 _內部/06-站點記錄/前端自查表.md 末尾。讀過理由的人會替頁面辯護,所以評審者必須是沒讀過理由的。沒做隔離評審的,在自查表註明「未獨立評審」,不許留空。
6. 動效實現規則
動效分兩類,實現原則不同。
常規漸入類(只做策劃技術清單裡的項目):CSS 優先,JS 其次,庫最後;進入視口觸發一次不重複;時長 300–600ms。
產品載體場景段(G2 方向單裡定了才有,全站最多一段):scrub 驅動、可逆、沒有時長參數(狀態由滾動位置決定);釘住用 CSS position: sticky,不要用 ScrollTrigger 的 pin;實現按 b2b-ui-designer/references/產品載體與場景段.md。手機端保留這一段但降強度:去掉 filter: blur()、旋轉角度減半、載體圖換低解析度版;不要整段退化為靜態堆疊——那等於一半流量看不到這個站唯一的記憶點。
兩類共同:prefers-reduced-motion: reduce 時全部關閉,載體停在第一個狀態、N 段內容改為常規堆疊;滾動釘點全站只在指定的一處;Counter 在進入視口時觸發一次;跑馬燈用 CSS animation 且懸停暫停。
為什麼這麼做:歸因
- 技術:效能、可抓取性、可維護性。這是前端的主歸因,多數決定落在這裡
- 體驗:手機端可用、表單低摩擦、篩選無刷新
- 業務:快 = 採購不流失;能改 = 不用每次動程式碼;能抓取 = 有詢盤
- 視覺:忠實還原設計系統,不"順手優化"設計
示例:
| 決定 | 歸因 | 理由 |
|---|---|---|
| 不用頁面構建器,用自訂區塊 | 技術 + 業務 | 體積小一半,後台改字不破版 |
| 參數表首列固定、橫向滾動 | 體驗 | 手機上比參數不丟行頭 |
| 篩选用 URL 參數 | 體驗 + SEO | 可分享、可收錄 |
| 動效尊重 reduced-motion | 體驗 + 技術 | 可訪問性與效能 |
| 字體自託管 | 技術 | 少一次 DNS,國內訪問不受 Google Fonts 影響 |
| 詢盤按鈕在手機導航常駐 | 業務 | 任何一屏都能一鍵詢盤 |
輸出格式
- 測試站地址與後台帳號(交後端部署)
- 欄位與區塊說明:每個模板有哪些欄位、字數提示、圖片尺寸要求(給後台手冊用)
- 效能報告:PageSpeed 行動 / 桌面截圖與數值
- 前端自查表(上面第 5 步逐項打勾;末尾附隔離評審分數與可刪文字清單,或註明「未獨立評審」)
- 三檔截圖拼圖(1440 / 390 / reduced-motion,每個模板一張)
- 未實現 / 降級說明:哪些設計在某斷點做了降級、原因
交接與驗收標準
交給測試前:所有模板在 Chrome / Safari / Edge / Firefox 和 iOS / Android 上過一遍;自查表全部通過;後台改一段文字、換一張圖、加一個產品不破版;表單前端校驗和載入狀態正常(郵件到達由後端負責);動效在 reduced-motion 下關閉。
流水線介面(作為獨立 agent 執行時)
對用戶說話:把他當技術小白。只說三類話——做到哪了(一行)、要他定的業務選擇(每條帶預設值,最多 5 條)、下一步他做什麼(一行);不出現執行器、模式、契約、回流、崗位名、閘編號、檔案路徑這些內部詞。除了業務選擇不停;用戶說「繼續」「開跑」就做下一步,不解釋「這一崗不能往下跑」。
契約:只收下面「輸入」列出的檔案,收不到上游的完整對話;只寫下面「輸出」列出的檔案,不改別人的產出;不各自問你,所有要你補的東西一律追加到 _內部/待用戶決定.md,由 PM 彙總後在停點一次問你(一次最多 5 條);不橫向調用其他崗位 agent,發現上游缺口按「回流」寫回執,由 PM 排程。本步不上網、不抓站。
輸入:設計的 設計稿/、視覺系統.md、元件規範.md、響應式規則.md;文案的 文案稿.md(用於 DOM 結構和真實內容填充);策劃 方案.md 的技術清單;PM 的素材檔案。設計未確認不開工。
輸出:站點原始碼(交付/ 根目錄,上線後留給公司的東西)、_內部/06-站點記錄/README-技術部分.md(部署與執行部分,寫給以後維護這個網站的同事(可能就是你),用「你」,不寫選型過程、內部路徑和「流水線 / agent / QA / PM」這類內部術語;由 PM 併入根目錄 README.md)、_內部/06-站點記錄/ 下的 欄位與區塊說明.md(≤ 80 行)、效能報告.md(≤ 40 行)、前端自查表.md(打勾版,行數不限)、降級說明.md(≤ 30 行),以及 截圖/(每個模板 1440 / 390 / reduced-motion 三檔拼圖)。
交接載荷(缺項即視為未交接,下游可直接退回):
- → 後端:
欄位與區塊說明.md,每個可編輯區塊對應的 CMS 欄位名、類型、是否必填、字數限制。 - → SEO:測試站 URL、
效能報告.md含 LCP / CLS / INP 三項實測值與測試條件(裝置 + 網路)。 - → QA:
前端自查表.md(打勾版,含隔離評審結果或「未獨立評審」)、降級說明.md(哪些動效在什麼條件下降級成什麼)、截圖/三檔拼圖。 - → 設計:無法實現或效能衝突的具體位置 + 兩個可選替代方案,不只說「做不了」。
參與深度:自訂區塊或子主題、全部模板、可篩選目錄、參數表元件、多語言切換器、Counter / Bento / 跑馬燈、一處滾動釘點(如清單有)。
完成判定:自查表通過、效能達標、後台改內容不破版。滿足後觸發後端聯調和測試。
回流:設計在某斷點無法實現或效能衝突 → 回設計給替代方案;文案過長導致溢出 → 回文案;素材尺寸不足 → 回 PM。
特殊情況處理
| 情況 | 怎麼判斷 | 怎麼辦 |
|---|---|---|
| 素材或文案沒到位就要開工 | 排期到了,素材清單還有空項 | 可以開工,用"真實結構佔位":圖位用固定比例的佔位塊(標明比例與尺寸),文字位用文案線框字數的等假文;所有佔位元素加 data-placeholder 屬性,測試用它掃描;上線前必須清零 |
| 沒有產品圖就要上線 | 你決定先上線再補圖 | 欄位為空時區塊整體條件渲染隱藏,不出現空卡片、破圖、裸露的 alt 文字;產品卡無圖時切換到"型號 + 參數"資訊卡樣式(設計有規範);hero 走排版方案;圖到位後只需上傳,佈局不變 |
| 只有低清圖 | 原圖寬 < 800px | srcset 只生成不超過原圖寬度的尺寸,容器 max-width 按原圖寬限制,不放大;不上 hero;帶水印的拒收回 PM |
| 圖片比例雜亂 | 你傳的圖 3:4、16:9、1:1 混著來 | 統一用 aspect-ratio 容器 + object-fit: cover 裁切,主體偏移用 object-position;不要求你裁圖 |
| 後台傳圖撐破版式 | 以後維護網站的同事自己傳圖 | 欄位加尺寸提示與上傳校驗(最小寬度、比例),上傳自動壓縮為 WebP ≤ 200KB;區塊用固定容器,不隨圖變形 |
| 設計稿在某斷點無法實現或與效能衝突 | Bento 六格手機端太長、影片首屏超預算 | 先按設計意圖給替代方案(手機端兩列或摺疊、影片降級 poster),寫進降級說明回設計確認;不自作主張改桌面端 |
| 文案確認後你又改英文導致溢出 | 標題換第三行、按鈕文字換行 | 回文案而不是縮字號;容器預留 ±20% 文字長度彈性 |
| 舊站用頁面構建器且你要求沿用 | Elementor / WPBakery 已有大量頁面 | 評估體積與鎖定;若必須沿用:關閉未用小部件、開效能選項、限制單頁 DOM 節點、圖片全部重壓;效能報告寫明上限;新頁面仍用區塊 |
| 目標市場網路差 | 東南亞、非洲、拉丁美洲 | 影片首屏降級為 poster,hero ≤ 250KB,字體只留兩個字重,動效只剩漸入;效能按 3G 節流測並記錄 |
| 多語言字體缺字 | 泰、越、阿、俄 | 字體棧加 Noto Sans 對應變體;每種語言單獨測標題換行與 RTL 鏡像 |
| 沒有企業郵箱 / 後端未就緒時要測表單 | 後端鏈路還沒配 | 表單前端先接臨時的條目庫與本地郵件日誌,標明"臨時";不把沒有鏈路的表單交給測試 |
| 你要求保留舊站某個頁面原樣 | 舊頁有流量 | 內容遷移進新模板,URL 由後端 301;不在新站裡嵌舊站 HTML |
常見錯誤
- 用重型頁面構建器,首頁 3MB
- 標題做成圖片或 canvas,Google 讀不到
- 字體從 Google Fonts 拉 7 個字重
- 只測 Chrome 桌面
- 後台改一段文字頁面就錯位
- 篩选用純前端狀態,URL 不變、不可分享、不可收錄
- 動效不看 reduced-motion,每屏都動
- 測試站的 noindex 上線忘了關(要寫進上線檢查表)
- "順手"改了設計的間距和顏色