商用網站架設實務

LESSON-23 · solution

專案規劃與設計

這一頁不是直接複製答案;先逐檔看差異、修改原因與驗收證據,再把需要的改動帶回自己的資料夾。 這頁用 可觀察證據anchor 指出下一個動作。

Starter4 個小成果
Checkpoint一個核心缺口
Solution5 個差異

開始前確認

這一頁的結果:四頁 sitemap、四個 user tasks 與優先級完整;Acceptance checklist 與 evidence.md 可逐項重現;沒有 TODOCHECKPOINT 或未教的外部整合,390px 與 Tab 仍可操作

工作方式:先把這一階段複製到自己的工作資料夾,開啟 files/index.html,記下修改前的畫面、Elements、Console、鍵盤 focus 與 brief 內容狀態。

會用到的檔案:index.htmlstyle.cssmain.jsproject-brief.mdevidence.md

本堂焦點:把服務型商家需求整理成可執行的 project brief

照這個順序做

一次只做一張卡。完成後先重新整理入口,再留下證據,才進入下一張。

差異 1

先定義要服務誰與要解決什麼,再決定頁面內容。

目的

先定義要服務誰與要解決什麼,再決定頁面內容。

修改檔案

project-brief.md

程式碼位置

角色與目標

現在要做:先對照差異,再檢查 在 project-brief.md 的「角色與目標」對照這項變更:- 目標商家:安心到府服務;訪客:第一次尋找居家維護的屋主;目標:理解方案後送出諮詢 - 驗收證據:在自己的工作資料夾留下這一項紀錄。

貼上位置:project-brief.md 的 角色與目標 區塊

- 目標商家:安心到府服務;訪客:第一次尋找居家維護的屋主;目標:理解方案後送出諮詢
- 驗收證據:在自己的工作資料夾留下這一項紀錄。

預期結果:brief 能用一句話說明目標商家、訪客與訪客要完成的結果。

驗收證據:project-brief.md 的角色、目標與主要 CTA 可以逐項對照。

卡住時先看這裡

常見錯誤:只複製完整答案,卻沒有先理解這一項差異的責任。

第一個檢查:只對照目前差異指定的檔案與 anchor。

差異 2

把頁面範圍與每頁唯一責任固定下來,避免之後每頁重複或漏頁。

目的

把頁面範圍與每頁唯一責任固定下來,避免之後每頁重複或漏頁。

修改檔案

project-brief.md

程式碼位置

Sitemap table

現在要做:先對照差異,再檢查 在 project-brief.md 的「Sitemap table」對照這項變更:| 頁面 | URL | 主要責任 | 主要 CTA | | --- | --- | --- | --- | | 首頁 | index.html | 建立信任並引導查看服務 | 查看服務方案 | | 服務 | services.html | 讓訪客比較方案 | 了解適合方案 | | 關於 | about.html | 說明背景與服務方式 | 認識我們如何協助 | | 聯絡 | contact.html | 收集諮詢需求 | 送出諮詢 |

貼上位置:project-brief.md 的 Sitemap table 區塊

| 頁面 | URL | 主要責任 | 主要 CTA |
| --- | --- | --- | --- |
| 首頁 | index.html | 建立信任並引導查看服務 | 查看服務方案 |
| 服務 | services.html | 讓訪客比較方案 | 了解適合方案 |
| 關於 | about.html | 說明背景與服務方式 | 認識我們如何協助 |
| 聯絡 | contact.html | 收集諮詢需求 | 送出諮詢 |

預期結果:四列 sitemap 都有檔名、頁面責任與下一步,且不包含尚未教的技術細節。

驗收證據:project-brief.md 的 Sitemap 表格列出四個 HTML 檔案與四個主要 CTA

卡住時先看這裡

常見錯誤:只複製完整答案,卻沒有先理解這一項差異的責任。

第一個檢查:只對照目前差異指定的檔案與 anchor。

差異 3

把頁面規劃連到真實訪客行動,再決定哪些結果必須先完成。

目的

把頁面規劃連到真實訪客行動,再決定哪些結果必須先完成。

修改檔案

project-brief.md

程式碼位置

User tasks 與 priority

現在要做:先對照差異,再檢查 在 project-brief.md 的「User tasks 與 priority」對照這項變更:| 優先級 | User task | | --- | --- | | P0 | 當我是第一次訪客,我想理解服務並前往服務頁,以便判斷是否適合。 | | P0 | 當我找到合適方案,我想送出諮詢,以便開始聯絡。 | | P1 | 當我想確認商家可信度,我想閱讀關於頁,以便降低疑慮。 | | P2 | 當我想快速回到服務頁,我想使用主要導覽,以便縮短尋找時間。 |

貼上位置:project-brief.md 的 User tasks 與 priority 區塊

| 優先級 | User task |
| --- | --- |
| P0 | 當我是第一次訪客,我想理解服務並前往服務頁,以便判斷是否適合。 |
| P0 | 當我找到合適方案,我想送出諮詢,以便開始聯絡。 |
| P1 | 當我想確認商家可信度,我想閱讀關於頁,以便降低疑慮。 |
| P2 | 當我想快速回到服務頁,我想使用主要導覽,以便縮短尋找時間。 |

預期結果:四個任務都使用『當……我想……以便……』句型,且 P0/P1/P2 能說明優先順序。

驗收證據:project-brief.md 的 User tasks 表格與 Priority 區塊。

卡住時先看這裡

常見錯誤:只複製完整答案,卻沒有先理解這一項差異的責任。

第一個檢查:只對照目前差異指定的檔案與 anchor。

差異 4

把 Markdown 規劃轉成可以在瀏覽器檢查的最小畫面,不把它誤認成已完成的四頁網站。

目的

把 Markdown 規劃轉成可以在瀏覽器檢查的最小畫面,不把它誤認成已完成的四頁網站。

修改檔案

index.html

程式碼位置

project preview page-plan

現在要做:先對照差異,再檢查 在 index.html 的「project preview page-plan」對照這項變更:<ol id="page-plan"></ol> <p id="baseline-status" role="status">尚未檢查規劃預覽</p> <button id="baseline-action" type="button">檢查預覽</button>

貼上位置:index.html 的 project preview page-plan 區塊

<ol id="page-plan"></ol>
<p id="baseline-status" role="status">尚未檢查規劃預覽</p>
<button id="baseline-action" type="button">檢查預覽</button>

預期結果:預覽入口有唯一 h1、四個頁面項目、規劃邊界說明與可操作的狀態按鈕。

驗收證據:畫面上的四個 li、#baseline-status 文字、Console 訊息與 Tab focus

卡住時先看這裡

常見錯誤:只複製完整答案,卻沒有先理解這一項差異的責任。

第一個檢查:只對照目前差異指定的檔案與 anchor。

差異 5

把規劃從描述文件收斂成之後可以逐項檢查的交付契約。

目的

把規劃從描述文件收斂成之後可以逐項檢查的交付契約。

修改檔案

project-brief.md

程式碼位置

Acceptance checklist

現在要做:先對照差異,再檢查 在 project-brief.md 的「Acceptance checklist」對照這項變更:- [ ] 四個頁面檔名與每頁責任已在 sitemap 對照 - [ ] P0 任務都有清楚的訪客動作與預期結果 - [ ] 390px 與純 Tab 操作的觀察方式已寫出 - evidence.md 記錄檔案、操作、預期、實際與結果

貼上位置:project-brief.md 的 Acceptance checklist 區塊

- [ ] 四個頁面檔名與每頁責任已在 sitemap 對照
- [ ] P0 任務都有清楚的訪客動作與預期結果
- [ ] 390px 與純 Tab 操作的觀察方式已寫出
- evidence.md 記錄檔案、操作、預期、實際與結果

預期結果:清單至少涵蓋四頁檔案、主要任務與窄版/鍵盤觀察,且 evidence.md 能記錄預期與實際結果。

驗收證據:project-brief.md 有四項 checklist;evidence.md 有檔案、操作、預期、實際與結果欄位。

卡住時先看這裡

常見錯誤:只複製完整答案,卻沒有先理解這一項差異的責任。

第一個檢查:只對照目前差異指定的檔案與 anchor。

階段檔案

完整檔案收在可展開的卡片中;先完成上方微步驟,再用這裡查閱與複製。檔案位置要和目前的相對路徑一致。

開啟 solution 的可執行入口

index.html離線預覽入口:將 project brief 的頁面規劃呈現成可觀察清單。

這段要貼在哪裡:先在自己的工作資料夾建立同名相對位置,再複製內容。

<!doctype html>
<html lang="zh-Hant">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>LESSON-23|Project brief 規劃練習|solution</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <main class="page-shell">
    <p class="eyebrow">LESSON-23 · solution</p>
    <h1>Project brief 規劃預覽</h1>
    <p class="page-description">完整結果:規劃檔、離線預覽與 evidence.md 可以互相對照;本堂仍不建立真正四頁或外部串接。</p>
    <section class="project-preview" aria-labelledby="preview-title">
      <h2 id="preview-title">網站地圖草稿</h2>
      <p>這是規劃成果的離線預覽,不代表四個正式頁面已完成。</p>
      <ol id="page-plan">
    <li><strong>首頁</strong>|index.html|建立信任並引導查看服務</li>
    <li><strong>服務</strong>|services.html|讓訪客比較方案</li>
    <li><strong>關於</strong>|about.html|說明背景與服務方式</li>
    <li><strong>聯絡</strong>|contact.html|收集諮詢需求</li>
      </ol>
    </section>
    <p id="baseline-status" class="status" role="status" aria-live="polite">尚未檢查規劃預覽</p>
    <button id="baseline-action" type="button">檢查預覽項目</button>
  </main>
  <script src="main.js" defer></script>
</body>
</html>
style.css呈現層:控制規劃預覽、按鈕 focus 與窄版可讀性。

這段要貼在哪裡:先在自己的工作資料夾建立同名相對位置,再複製內容。

:root { font-family: system-ui, -apple-system, "Segoe UI", "Noto Sans TC", sans-serif; color: #17324d; background: #f5f8fb; }
* { box-sizing: border-box; }
body { margin: 0; min-height: 100vh; line-height: 1.7; }
.page-shell { width: min(100% - 2rem, 760px); margin: 2rem auto; padding: 2rem; border: 1px solid #cbd8e4; border-radius: 20px; background: #fff; }
.eyebrow { color: #176b87; font-weight: 800; letter-spacing: .06em; }
.page-description { color: #52657d; }
.project-preview { margin-top: 1.5rem; }
.project-preview ol { display: grid; gap: .75rem; padding-left: 1.5rem; }
.project-preview li { padding: .75rem; border: 1px solid #d7e0eb; border-radius: .75rem; background: #f8fbfd; }
.status { min-height: 2rem; color: #17643d; font-weight: 700; }
button { padding: .65rem .9rem; border: 0; border-radius: 9px; background: #176b87; color: #fff; font: inherit; cursor: pointer; }
button:focus-visible, a:focus-visible { outline: 3px solid #1d4ed8; outline-offset: 3px; }
@media (max-width: 560px) { .page-shell { margin: 1rem auto; padding: 1rem; } h1 { font-size: 1.65rem; } }
@media (prefers-reduced-motion: reduce) { * { scroll-behavior: auto; } }
main.js觀察腳本:讀取實際 li 數量,更新 status 並留下 Console 證據。

這段要貼在哪裡:先在自己的工作資料夾建立同名相對位置,再複製內容。

const planList = document.querySelector("#page-plan");
const status = document.querySelector("#baseline-status");
const action = document.querySelector("#baseline-action");

function inspectPlan() {
  const count = planList ? planList.querySelectorAll("li").length : 0;
  if (status) status.textContent = "目前預覽有 " + count + " 個頁面項目";
  console.log("LESSON-23:實際預覽項目數", count);
}

if (action) action.addEventListener("click", inspectPlan);
console.log("LESSON-23:規劃預覽入口已載入");
project-brief.md規劃契約:記錄角色、sitemap、user tasks、優先級與驗收條件。

這段要貼在哪裡:先在自己的工作資料夾建立同名相對位置,再複製內容。

# Project brief|安心到府服務

## 角色與目標

- 目標商家:安心到府服務
- 訪客:第一次尋找居家維護的屋主
- 目標:理解方案後送出諮詢

## Sitemap table

| 頁面 | URL | 主要責任 | 主要 CTA |
| --- | --- | --- | --- |
| 首頁 | index.html | 建立信任並引導查看服務 | 查看服務方案 |
| 服務 | services.html | 讓訪客比較方案 | 了解適合方案 |
| 關於 | about.html | 說明背景與服務方式 | 認識我們如何協助 |
| 聯絡 | contact.html | 收集諮詢需求 | 送出諮詢 |

## User tasks 與 priority

| 優先級 | User task |
| --- | --- |
| P0 | 當我是第一次訪客,我想理解服務並前往服務頁,以便判斷是否適合。 |
| P0 | 當我找到合適方案,我想送出諮詢,以便開始聯絡。 |
| P1 | 當我想確認商家可信度,我想閱讀關於頁,以便降低疑慮。 |
| P2 | 當我想快速回到服務頁,我想使用主要導覽,以便縮短尋找時間。 |

## Acceptance checklist

- [ ] 規劃入口可以開啟
- [ ] 四個頁面檔名與每頁責任已在 sitemap 對照
- [ ] P0 任務都有清楚的訪客動作與預期結果
- [ ] 390px 與純 Tab 操作的觀察方式已寫出
- [ ] evidence.md 記錄檔案、操作、預期、實際與結果

## 範圍

- 本堂只做 planning-only 規劃,不建立真正四頁、不連外部服務、不部署。
evidence.md驗收紀錄:保存修改檔案、操作、預期、實際與結果。

這段要貼在哪裡:先在自己的工作資料夾建立同名相對位置,再複製內容。

# 驗收證據

| 欄位 | 紀錄 |
| --- | --- |
| 修改檔案 | project-brief.md、index.html、evidence.md |
| 操作 | 開啟預覽、按下檢查按鈕、用 Tab 走到按鈕、在 390px 檢查內容 |
| 預期 | 四頁、四個 user tasks、優先級與 checklist 可對照 |
| 實際 | 預覽顯示 4 個頁面項目,status 與 Console 顯示實際數量 |
| 結果 | 通過;本堂未建立正式頁面、外部服務或部署 |

完成驗收

下一步

Solution 對照完成後,回到 README 整理證據,並準備下一堂課的先備知識。

回到 README,整理本堂證據並銜接下一堂