LESSON-08 · 自主延伸

首頁 CSS 組裝與 landmarks

把「首頁 CSS 組裝與 landmarks」拆成 4 個可獨立完成、可重設、可驗證的自主學習 module。

1. 現在要做什麼

成果:完成採單一基底、間距尺度、元件責任與語意 shell 的首頁。

需要的檔案:files/starter/index.html(整合起點,保留跨 module 的最小缺口。)

完成後:完成採單一基底、間距尺度、元件責任與語意 shell 的首頁。

0 / 8 個操作已記錄

2. 先備自我檢查

逐項展開;答不出來時先走補救連結,不必硬做。

已完成本章基礎練習並能找到 Starter。

自我檢查:我能否指出本章 Starter 入口與唯一 TODO?

不足時補救:回到本章 README,先完成基礎練習與入口導覽。

能開啟本機 HTML 並讀取至少一種瀏覽器證據。

自我檢查:我能否開啟 Elements、Console 或 Network 並找到本頁?

不足時補救:先開 DevTools,重新整理一次,確認目前文件與第一筆 request。

3. 完整學習目標與 Learning Map

每一個目標只對應一個 module;成功狀態必須能指出證據。

能用最小 base 規則統一 box-sizing、body margin 與媒體元素最大寬度,不抹除必要的互動狀態。

為什麼重要
瀏覽器預設與 content-box 計算若未先統一,元件尺寸容易因 padding/border 超出;過度 reset 又可能移除焦點與語意提示。
完成條件
在固定寬度卡片上切換 base-reset class,讀取 box-sizing 前後值,並檢查本地 img 不超過容器。
成功狀態
runtime 的 box-sizing 由 content-box 變 border-box;base fixture 同時保留 body spacing reset、img max-width 與按鈕 focus。
證據位置
runtime before=content-box、after=border-box、property=box-sizing;窄版圖片外框不超過父容器

能用有限 spacing scale 管理 section 間距,讓相同層級只出現可預測的節奏值。

為什麼重要
每個區塊各寫任意 margin 會逐頁漂移;token 化節奏能讓新增內容仍維持一致層級與密度。
完成條件
把第二個 section 的任意 13px margin-block-start 切換為 --space-lg 的 32px。
成功狀態
runtime 的 margin-block-start 由 13px 變 32px;其他相同層級 section 使用同一 token。
證據位置
runtime before=13px、after=32px、property=margin-block-start

能讓 component class 負責完整卡片外觀,utility class 只增加單一可預測的間距責任。

為什麼重要
若 utility 重複背景、邊框等元件責任,class 組合會互相覆蓋;分工清楚才能安全重用。
完成條件
卡片初始只有 service-card,執行後 class attribute 加入 space-stack-lg,但保留元件 class。
成功狀態
runtime class 由 service-card 變 service-card space-stack-lg;背景/邊框仍由 service-card,margin 只由 utility 提供。
證據位置
runtime before=service-card、after=service-card space-stack-lg、attribute=class;Styles 顯示 margin 與外觀分屬兩條規則

4. 4 個知識模組與 Micro Labs

依序展開;每次只改一項,操作後確認該模組自己的 DOM、progress 與 evidence。

1base/reset

完整解釋

白話:base 是全站共同起跑線,只先處理大家都需要的一小組預設,不是把瀏覽器所有樣式清空。

正式說法:A minimal reset normalizes selected user-agent defaults;box-sizing:border-box includes padding and border in the specified box size, while inherited universal rules cover pseudo-elements deliberately。

何時使用:開始組裝多個元件前,需要可預測盒模型、頁面外距與媒體縮放時。

修改前後:Before:width:16rem 再加 padding/border 會超出指定尺寸。After:border-box 讓外框維持 16rem。

常見混淆:reset 不等於 design system;它只建立基底,不負責卡片品牌色、section 間距或元件狀態。

名詞與最小範例

base/reset Minimal base styles and reset

白話
base 是全站共同起跑線,只先處理大家都需要的一小組預設,不是把瀏覽器所有樣式清空。
正式定義
A minimal reset normalizes selected user-agent defaults;box-sizing:border-box includes padding and border in the specified box size, while inherited universal rules cover pseudo-elements deliberately。
何時使用
開始組裝多個元件前,需要可預測盒模型、頁面外距與媒體縮放時。
最小範例
*,*::before,*::after{box-sizing:border-box}body{margin:0}img{display:block;max-width:100%;height:auto}
驗收證據
runtime before=content-box、after=border-box、property=box-sizing;窄版圖片外框不超過父容器
常混淆
reset 不等於 design system;它只建立基底,不負責卡片品牌色、section 間距或元件狀態。

Micro Lab|base/reset

情境:首頁卡片設定 16rem 後仍因 1rem padding 與 border 撐寬,圖片在手機又超出卡片。

起始狀態:卡片使用 content-box;fixture 另保留 max-width:100% 的媒體基底與可見 focus 規則。

  1. 執行實驗替卡片切換 base-reset class,直接讀取 computed box-sizing。
  2. 執行下方操作,觀察獨立的 DOM 與資料狀態。
  3. 依證據欄位重新驗收。

目前主題:base/reset

尚未執行;DOM data-state=starter。

預期:runtime 的 box-sizing 由 content-box 變 border-box;base fixture 同時保留 body spacing reset、img max-width 與按鈕 focus。

證據:runtime before=content-box、after=border-box、property=box-sizing;窄版圖片外框不超過父容器

第一個檢查:在 Computed 先讀 box-sizing,不先任意減少 width。

重設:重新載入 module,移除 base-reset class。

卡住時

  • 症狀:切成 border-box 後卡片仍超出父層。
    可能原因:卡片另有 min-width、transform 或長字串根因,並非盒模型單一問題。
    先檢查:比較卡片 width/min-width/scrollWidth 與父層 clientWidth。
    修正:保留 border-box,再針對第一個超寬 property 或內容修正。

理解檢查

最小 reset 最重要的原則是什麼?

尚未作答。

查看解釋

reset 是共同起點,不應破壞 focus 或取代元件設計。

本模組官方來源:MDN|box-sizing

2區塊間距節奏

完整解釋

白話:間距像音樂拍子,選少量固定拍點反覆使用,比每次憑感覺留白更整齊。

正式說法:A spacing scale is a constrained set of design token values used according to structural relationships;margin-block expresses vertical rhythm in logical flow direction。

何時使用:首頁 hero、服務、案例、CTA 等同層區塊需要一致分隔時。

修改前後:Before:section 間距混用 13px、27px、35px。After:同層級統一 --space-lg,元件內另用 --space-sm/md。

常見混淆:spacing rhythm 不是所有距離都一樣;不同結構層級可使用不同 token,但每層用途要一致。

名詞與最小範例

區塊間距節奏 Section spacing rhythm

白話
間距像音樂拍子,選少量固定拍點反覆使用,比每次憑感覺留白更整齊。
正式定義
A spacing scale is a constrained set of design token values used according to structural relationships;margin-block expresses vertical rhythm in logical flow direction。
何時使用
首頁 hero、服務、案例、CTA 等同層區塊需要一致分隔時。
最小範例
:root{--space-sm:.5rem;--space-md:1rem;--space-lg:2rem}.page-section+.page-section{margin-block-start:var(--space-lg)}
驗收證據
runtime before=13px、after=32px、property=margin-block-start
常混淆
spacing rhythm 不是所有距離都一樣;不同結構層級可使用不同 token,但每層用途要一致。

Micro Lab|區塊間距節奏

情境:首頁四個 section 各自由不同人加入,垂直留白看似相近卻沒有一致規則。

起始狀態:第二個 section 使用任意 13px margin-block-start。

  1. 執行實驗替第二個 section 切換 use-spacing-token class,讀取 computed margin-block-start。
  2. 執行下方操作,觀察獨立的 DOM 與資料狀態。
  3. 依證據欄位重新驗收。

目前主題:區塊間距節奏

服務
案例
尚未執行;DOM data-state=starter。

預期:runtime 的 margin-block-start 由 13px 變 32px;其他相同層級 section 使用同一 token。

證據:runtime before=13px、after=32px、property=margin-block-start

第一個檢查:在 Computed 讀第二個 section 的 margin-block-start,先記錄目前是否屬於 spacing scale。

重設:重新載入 module,移除 use-spacing-token class。

卡住時

  • 症狀:切換後 margin 仍是 13px。
    可能原因:utility class 沒命中第二個 section,或後方規則覆蓋 token 宣告。
    先檢查:查看 class list、Styles 規則順序與 --space-lg 的 computed value。
    修正:讓 .use-spacing-token 在相同 specificity 下後寫,且 token 定義為 2rem。

理解檢查

spacing scale 的主要價值是什麼?

尚未作答。

查看解釋

有限 token 能建立一致節奏,又允許不同層級使用不同值。

本模組官方來源:MDN|margin-block-start

3元件 class 與 utility class

完整解釋

白話:component 是完整家具,utility 像只加一個墊高腳;utility 不應重新打造整張椅子。

正式說法:A component class groups cohesive visual/state rules for a reusable UI unit;a utility class exposes one narrow declaration responsibility intended for composition。

何時使用:同一卡片元件在不同頁面只需調整一項間距、對齊或顯示輔助時。

修改前後:Before:每個頁面複製 service-card 並改 margin。After:service-card 保持一致,space-stack-lg 單獨控制外距。

常見混淆:utility 不是任意 override;若一個 class 同時改背景、border、padding 與字體,它已不像單一用途 utility。

名詞與最小範例

元件 class 與 utility class Component and utility classes

白話
component 是完整家具,utility 像只加一個墊高腳;utility 不應重新打造整張椅子。
正式定義
A component class groups cohesive visual/state rules for a reusable UI unit;a utility class exposes one narrow declaration responsibility intended for composition。
何時使用
同一卡片元件在不同頁面只需調整一項間距、對齊或顯示輔助時。
最小範例
.service-card{background:var(--surface);border:1px solid var(--border)}.space-stack-lg{margin-block-start:2rem}
驗收證據
runtime before=service-card、after=service-card space-stack-lg、attribute=class;Styles 顯示 margin 與外觀分屬兩條規則
常混淆
utility 不是任意 override;若一個 class 同時改背景、border、padding 與字體,它已不像單一用途 utility。

Micro Lab|元件 class 與 utility class

情境:同一張服務卡在首頁需要較大上距,但在列表頁不需要;團隊不想複製第二套卡片 class。

起始狀態:卡片只有 service-card,外觀完整但沒有額外上距。

  1. 執行實驗將卡片 class attribute 由 service-card 改為 service-card space-stack-lg,保留元件責任並加入單一 utility。
  2. 執行下方操作,觀察獨立的 DOM 與資料狀態。
  3. 依證據欄位重新驗收。

目前主題:元件 class 與 utility class

服務卡片
尚未執行;DOM data-state=starter。

預期:runtime class 由 service-card 變 service-card space-stack-lg;背景/邊框仍由 service-card,margin 只由 utility 提供。

證據:runtime before=service-card、after=service-card space-stack-lg、attribute=class;Styles 顯示 margin 與外觀分屬兩條規則

第一個檢查:先列出 service-card 目前負責的 background、border、padding,再確認 utility 只改 margin。

重設:重新載入 module,class 回到 service-card。

卡住時

  • 症狀:加入 utility 後卡片背景或邊框也變了。
    可能原因:utility class 混入多項外觀宣告,或命名指向一整套變體。
    先檢查:在 Styles 展開 utility 規則,數出它修改的 properties。
    修正:讓 space-stack-lg 只保留 margin-block-start,其他宣告回到 component。

理解檢查

哪一個規則較符合 utility class?

尚未作答。

查看解釋

utility 應維持單一、可預測、可組合的責任。

本模組官方來源:MDN|Class selectors

5. 首頁 CSS 組裝與 landmarks|整合 Lab

情境:在同一份章節作品中整合 4 個 module,排除單項通過但組合失敗的問題。

交付:完成採單一基底、間距尺度、元件責任與語意 shell 的首頁。

尚未執行整合步驟。
  1. 1觀察整合 Starter 並找出第一個未通過 module。

    檔案:files/starter/index.html 定位:#observe

    操作:逐項讀取 outcomes,執行一次現況操作。

    // OBSERVE:不修改程式,先記錄第一個失敗 moduleId。

    預期:能指出第一個未通過 module。

    證據:第一個 moduleId 與缺少的 evidence。

    原因:先觀察可避免未重現就直接改答案。

    卡住先查:確認開啟的是 files/starter/index.html。

  2. 2依 module 順序修改,一次只加入一個責任。

    檔案:files/starter/index.html 定位:#modify

    操作:執行實驗替卡片切換 base-reset class,直接讀取 computed box-sizing。 → 執行實驗替第二個 section 切換 use-spacing-token class,讀取 computed margin-block-start。 → 執行實驗將卡片 class attribute 由 service-card 改為 service-card space-stack-lg,保留元件責任並加入單一 utility。 → 執行 DOM collection probe,實際選取 header、nav、main、footer 並驗證唯一集合。

    // 08-01-base-reset: 執行實驗替卡片切換 base-reset class,直接讀取 computed box-sizing。
    // 08-02-topic: 執行實驗替第二個 section 切換 use-spacing-token class,讀取 computed margin-block-start。
    // 08-03-class-utility-class: 執行實驗將卡片 class attribute 由 service-card 改為 service-card space-stack-lg,保留元件責任並加入單一 utility。
    // 08-04-header-nav-main-footer-landmarks: 執行 DOM collection probe,實際選取 header、nav、main、footer 並驗證唯一集合。

    預期:完成採單一基底、間距尺度、元件責任與語意 shell 的首頁。

    證據:runtime before=content-box、after=border-box、property=box-sizing;窄版圖片外框不超過父容器;runtime before=13px、after=32px、property=margin-block-start;runtime before=service-card、after=service-card space-stack-lg、attribute=class;Styles 顯示 margin 與外觀分屬兩條規則;runtime count=4、uniqueCount=4、valid=true,text 包含品牌、主要導覽、服務內容與版權資訊

    原因:逐項整合能把回歸定位到明確 module。

    卡住先查:回到第一個未通過的 module,只修該處。

  3. 3驗證所有 module 在整合後仍成立。

    檔案:files/solution/index.html 定位:#verify

    操作:重新整理並依 outcomes 順序重跑所有證據。

    // VERIFY:逐項記錄 pass/fail,不以看到畫面代替 evidence。

    預期:4/4 module 通過。

    證據:每個 moduleId 都有實際結果與重設後重現紀錄。

    原因:單項通過不代表整合後沒有 selector、id 或狀態衝突。

    卡住先查:若失敗,回到第一個失敗 module,不同時修多項。

  4. 4把本章責任轉用到不同內容情境。

    檔案:files/starter/index.html 定位:#challenge

    操作:替另一個商家情境重做,仍達成:完成採單一基底、間距尺度、元件責任與語意 shell 的首頁。

    // CHALLENGE:只替換內容與資料,不新增框架或跳過 self-check。

    預期:完成採單一基底、間距尺度、元件責任與語意 shell 的首頁。

    證據:轉用後的作品與全數 module self-check。

    原因:能轉用才代表理解責任,而非只記住原範例。

    卡住先查:先確認共同基底與 module id 未被改壞。

重設方法:重新載入 files/starter/index.html;若 localStorage 不可用,使用頁面內記憶狀態並提供重設按鈕。

6. 自學挑戰與三層提示

挑戰:將同一組責任轉用到另一個商家情境,仍達成:完成採單一基底、間距尺度、元件責任與語意 shell 的首頁。

限制:不新增框架。;保留 module id 與驗收證據。

提交證據:提交可直接開啟的作品與逐項 self-check。

提示 1|方向提示

拆小:在「首頁 CSS 組裝與 landmarks」先完成第一個尚未通過的 module:base/reset,不同時修改其他責任。

提示 2|關鍵片段

串接:依 08-01-base-reset → 08-02-topic → 08-03-class-utility-class → 08-04-header-nav-main-footer-landmarks 核對各自輸入與證據。

提示 3|完整解答與原因

完整解答與原因:依序執行 執行實驗替卡片切換 base-reset class,直接讀取 computed box-sizing。 → 執行實驗替第二個 section 切換 use-spacing-token class,讀取 computed margin-block-start。 → 執行實驗將卡片 class attribute 由 service-card 改為 service-card space-stack-lg,保留元件責任並加入單一 utility。 → 執行 DOM collection probe,實際選取 header、nav、main、footer 並驗證唯一集合。;這個順序能把每個結果對回單一 module,避免整合後無法定位。

完整解答預設收合;先留下自己的嘗試,再開第三層。

7. 症狀式除錯指南

8. 理解測驗、驗收證據與下一步

哪個狀態代表 08-01-base-reset 完成?

尚未作答。

查看解釋

瀏覽器預設與 content-box 計算若未先統一,元件尺寸容易因 padding/border 超出;過度 reset 又可能移除焦點與語意提示。

哪個狀態代表 08-02-topic 完成?

尚未作答。

查看解釋

每個區塊各寫任意 margin 會逐頁漂移;token 化節奏能讓新增內容仍維持一致層級與密度。

哪個狀態代表 08-03-class-utility-class 完成?

尚未作答。

查看解釋

若 utility 重複背景、邊框等元件責任,class 組合會互相覆蓋;分工清楚才能安全重用。

哪個狀態代表 08-04-header-nav-main-footer-landmarks 完成?

尚未作答。

查看解釋

landmarks 讓鍵盤與輔助技術使用者快速跳到頁首、導覽、主要內容與頁尾;只有視覺 div 無法提供相同結構。

驗收清單

官方來源

回到課程地圖選擇下一章