LESSON-09 · 自主延伸

Grid 軌道、區域與內容尺寸

把「Grid 軌道、區域與內容尺寸」拆成 4 個可獨立完成、可重設、可驗證的自主學習 module。

1. 現在要做什麼

成果:完成具命名區域、隱式列與長內容安全的 Grid 版面。

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

完成後:完成具命名區域、隱式列與長內容安全的 Grid 版面。

0 / 8 個操作已記錄

2. 先備自我檢查

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

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

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

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

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

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

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

3. 完整學習目標與 Learning Map

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

能分辨 grid-template 宣告的 explicit tracks 與放不下新 item 時由 Grid placement 建立的 implicit tracks。

為什麼重要
資料筆數增加時,implicit rows 會真實參與版面;若只看模板欄數,容易誤判新增卡片的高度與位置。
完成條件
fixture 宣告兩欄一列但放入三個 items,執行後將 grid-auto-rows 由 auto 改成 56px。
成功狀態
runtime 的 grid-auto-rows 由 auto 變 56px;DOM 有 3 items,因此第三項位於模板外生成的 implicit row。
證據位置
runtime before=auto、after=56px、property=grid-auto-rows;DOM item count=3,模板容量第一列只有2項

能以矩形 named areas 表達 header、sidebar、main 的版面責任,並讓各 item 對應正確區域。

為什麼重要
area 名稱比匿名 line number 更能傳達版面意圖;非矩形或拼字不一致會使整個 template declaration 無效。
完成條件
兩欄 Grid 初始 grid-template-areas:none,執行後切換為兩列矩形 header/sidebar/main 區域。
成功狀態
runtime 的 grid-template-areas 由 none 變成包含 header header 與 sidebar main 的矩形定義。
證據位置
runtime before=none;after 包含 "header header" 與 "sidebar main";property=grid-template-areas

能區分容器的 align-items/justify-items 與單一 item 的 align-self/justify-self 覆寫。

為什麼重要
把 self 規則寫在容器或把 items 規則寫在 item,會讓對齊看似無效並引發多餘的 position/margin 修補。
完成條件
container 維持 align-items:stretch、justify-items:start,執行後只讓推薦 item 的 align-self 由 auto 變 end。
成功狀態
runtime 的 align-self 由 auto 變 end;其他 items 仍依容器 align-items:stretch。
證據位置
runtime before=auto、after=end、property=align-self;其他 item computed align-self 仍為 auto

能用 minmax(0,1fr) 解除 1fr 的內容型最小限制,並對不可斷長字串提供斷點。

為什麼重要
Grid 的 1fr 軌道仍可能受 min-content 撐寬;只隱藏 overflow 會裁掉內容,無法修正 track sizing 根因。
完成條件
兩欄 Grid 先使用 --tracks:1fr 1fr,再切換為兩個 minmax(0,1fr),並保留長 URL。
成功狀態
runtime 的 --tracks 由 `1fr 1fr` 變 `minmax(0,1fr) minmax(0,1fr)`;人工重測 Grid 不再橫向溢位。
證據位置
runtime before=`1fr 1fr`、after=`minmax(0,1fr) minmax(0,1fr)`、property=--tracks;人工證據為 scrollWidth<=clientWidth

4. 4 個知識模組與 Micro Labs

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

1explicit 與 implicit tracks

完整解釋

白話:explicit 是你先畫好的格線;implicit 是內容超出圖紙後,瀏覽器自動補出的新格子。

正式說法:Explicit grid is defined by grid-template-*;auto-placement creates implicit tracks when positioned items fall outside the explicit grid, sized by grid-auto-rows/columns。

何時使用:清單筆數不固定、Grid auto-placement 會新增列,或需要控制自動列高度時。

修改前後:Before:只看到兩欄就以為所有 tracks 都已宣告。After:同時檢查 template tracks、item 數與 grid-auto-rows。

常見混淆:implicit track 不是新增 DOM 元素;它是 layout algorithm 為現有 item 建立的軌道。

名詞與最小範例

explicit 與 implicit tracks Explicit and implicit grid tracks

白話
explicit 是你先畫好的格線;implicit 是內容超出圖紙後,瀏覽器自動補出的新格子。
正式定義
Explicit grid is defined by grid-template-*;auto-placement creates implicit tracks when positioned items fall outside the explicit grid, sized by grid-auto-rows/columns。
何時使用
清單筆數不固定、Grid auto-placement 會新增列,或需要控制自動列高度時。
最小範例
.grid{display:grid;grid-template-columns:repeat(2,1fr);grid-template-rows:3rem;grid-auto-rows:3.5rem}
驗收證據
runtime before=auto、after=56px、property=grid-auto-rows;DOM item count=3,模板容量第一列只有2項
常混淆
implicit track 不是新增 DOM 元素;它是 layout algorithm 為現有 item 建立的軌道。

Micro Lab|explicit 與 implicit tracks

情境:服務 Grid 原本只畫一列兩欄,API 加入第三筆服務後第二列高度與預期不同。

起始狀態:grid-template-columns 有兩欄、grid-template-rows 有一列,DOM 放入三個 items,grid-auto-rows:auto。

  1. 執行實驗替三 item grid 切換 size-implicit-row class,讀取 computed grid-auto-rows。
  2. 執行下方操作,觀察獨立的 DOM 與資料狀態。
  3. 依證據欄位重新驗收。

目前主題:explicit 與 implicit tracks

服務一
服務二
服務三
尚未執行;DOM data-state=starter。

預期:runtime 的 grid-auto-rows 由 auto 變 56px;DOM 有 3 items,因此第三項位於模板外生成的 implicit row。

證據:runtime before=auto、after=56px、property=grid-auto-rows;DOM item count=3,模板容量第一列只有2項

第一個檢查:先數直接 Grid items,再讀 grid-template-rows 與 grid-auto-rows。

重設:重新載入 module,移除 size-implicit-row class。

卡住時

  • 症狀:第三個 item 與前兩項重疊。
    可能原因:item 被手動指定到同一 grid cell,或容器沒有 display:grid。
    先檢查:查看三個 item 的 grid-row/grid-column 與父層 computed display。
    修正:移除不必要的手動 placement,保留 auto-placement 與 grid-auto-rows。

理解檢查

誰會在內容超出 explicit grid 時建立 implicit tracks?

尚未作答。

查看解釋

implicit tracks 是 Grid layout 為放置超出模板的 items 所建立。

本模組官方來源:MDN|Basic concepts of grid layout

2grid-template-areas

完整解釋

白話:先替版面格子取名字,再讓每個元件說自己要住進哪個區域。

正式說法:grid-template-areas defines named grid areas as strings;each named area must form a single filled rectangle, and items use grid-area to occupy it。

何時使用:頁面 shell 或 dashboard 有清楚區域責任,且希望 CSS 一眼表達結構時。

修改前後:Before:items 只靠 1/3 等 line numbers。After:模板與 items 使用 header/sidebar/main 名稱對應。

常見混淆:area name 不是 HTML id;它只存在於 Grid formatting context 的 CSS placement。

名詞與最小範例

grid-template-areas Named grid template areas

白話
先替版面格子取名字,再讓每個元件說自己要住進哪個區域。
正式定義
grid-template-areas defines named grid areas as strings;each named area must form a single filled rectangle, and items use grid-area to occupy it。
何時使用
頁面 shell 或 dashboard 有清楚區域責任,且希望 CSS 一眼表達結構時。
最小範例
.layout{grid-template-areas:"header header" "sidebar main"}.site-header{grid-area:header}
驗收證據
runtime before=none;after 包含 "header header" 與 "sidebar main";property=grid-template-areas
常混淆
area name 不是 HTML id;它只存在於 Grid formatting context 的 CSS placement。

Micro Lab|grid-template-areas

情境:兩欄後台版面使用大量 grid-column line numbers,維護者看不出每個區塊責任。

起始狀態:container 有兩欄但 grid-template-areas:none;三個 items 已具 grid-area 名稱。

  1. 執行實驗替 Grid container 切換 named-areas class,讀取 computed grid-template-areas。
  2. 執行下方操作,觀察獨立的 DOM 與資料狀態。
  3. 依證據欄位重新驗收。

目前主題:grid-template-areas

頁首
主要內容
尚未執行;DOM data-state=starter。

預期:runtime 的 grid-template-areas 由 none 變成包含 header header 與 sidebar main 的矩形定義。

證據:runtime before=none;after 包含 "header header" 與 "sidebar main";property=grid-template-areas

第一個檢查:在 Computed 讀 grid-template-areas,再核對每個 item 的 grid-area 拼字。

重設:重新載入 module,移除 named-areas class。

卡住時

  • 症狀:切換 class 後 grid-template-areas 仍為 none。
    可能原因:區域字串欄數不一致、同名區域不成矩形,或 declaration 拼字錯誤。
    先檢查:逐列數 area tokens,確認同名格連續形成矩形。
    修正:使用兩列各兩格的 `header header`、`sidebar main`。

理解檢查

named grid area 必須符合哪個形狀規則?

尚未作答。

查看解釋

非矩形 named area 會使 grid-template-areas declaration 無效。

本模組官方來源:MDN|grid-template-areas

3Grid item 對齊

完整解釋

白話:items 是老師對全班的規則,self 是某一位同學自己的例外。

正式說法:align-items/justify-items set the default self-alignment for all grid items on block/inline axes;align-self/justify-self override an individual item。

何時使用:同一 Grid 內大多數卡片使用共同對齊,只有推薦卡、徽章或 CTA 需要例外時。

修改前後:Before:為了移動單張卡修改整個 container。After:共同規則留在父層,單項例外使用 self。

常見混淆:align-content/justify-content 對齊的是整個 tracks 集合,不是單一 item 在 cell 裡的位置。

名詞與最小範例

Grid item 對齊 Grid item alignment

白話
items 是老師對全班的規則,self 是某一位同學自己的例外。
正式定義
align-items/justify-items set the default self-alignment for all grid items on block/inline axes;align-self/justify-self override an individual item。
何時使用
同一 Grid 內大多數卡片使用共同對齊,只有推薦卡、徽章或 CTA 需要例外時。
最小範例
.grid{align-items:stretch;justify-items:start}.featured{align-self:end}
驗收證據
runtime before=auto、after=end、property=align-self;其他 item computed align-self 仍為 auto
常混淆
align-content/justify-content 對齊的是整個 tracks 集合,不是單一 item 在 cell 裡的位置。

Micro Lab|Grid item 對齊

情境:三張方案卡都要拉滿列高,只有推薦 CTA 要貼齊 cell 底部。

起始狀態:container align-items:stretch;推薦 item align-self:auto。

  1. 執行實驗替推薦 item 切換 align-featured-end class,讀取 computed align-self。
  2. 執行下方操作,觀察獨立的 DOM 與資料狀態。
  3. 依證據欄位重新驗收。

目前主題:Grid item 對齊

一般卡
推薦卡
尚未執行;DOM data-state=starter。

預期:runtime 的 align-self 由 auto 變 end;其他 items 仍依容器 align-items:stretch。

證據:runtime before=auto、after=end、property=align-self;其他 item computed align-self 仍為 auto

第一個檢查:先確認被測節點是 Grid item,再分開讀父層 align-items 與自身 align-self。

重設:重新載入 module,移除 align-featured-end class。

卡住時

  • 症狀:align-self 改為 end 後位置不變。
    可能原因:該元素不是 Grid item,或 cell 沒有多餘 block-axis 空間可對齊。
    先檢查:確認父層 display:grid,並比較 item 與 grid area 的高度。
    修正:讓目標成為直接 Grid item,並提供大於 item 的 row size。

理解檢查

只改一個 Grid item 的 block-axis 對齊應使用什麼?

尚未作答。

查看解釋

self property 覆寫單一 item;items property 設定全體預設。

本模組官方來源:MDN|Box alignment in grid layout

4min-content 與長字串溢位

完整解釋

白話:1fr 會分空間,但軌道仍可能說『至少要放得下這串不能斷的文字』;把最小值設 0 才允許它縮。

正式說法:A flexible track has an automatic minimum that can honor min-content contribution;minmax(0,1fr) sets an explicit zero minimum, while overflow-wrap supplies break opportunities for long inline content。

何時使用:等寬 Grid 卡片含 URL、代碼或長單字,390px 下軌道被撐出 viewport 時。

修改前後:Before:repeat(2,1fr) 加 overflow:hidden。After:track 用 minmax(0,1fr),文字使用 overflow-wrap:anywhere。

常見混淆:min-content 是內容能在合法斷點下縮到的最小內在尺寸,不等於 CSS min-width 的固定數值。

名詞與最小範例

min-content 與長字串溢位 Min-content sizing and long-token overflow

白話
1fr 會分空間,但軌道仍可能說『至少要放得下這串不能斷的文字』;把最小值設 0 才允許它縮。
正式定義
A flexible track has an automatic minimum that can honor min-content contribution;minmax(0,1fr) sets an explicit zero minimum, while overflow-wrap supplies break opportunities for long inline content。
何時使用
等寬 Grid 卡片含 URL、代碼或長單字,390px 下軌道被撐出 viewport 時。
最小範例
.grid{--tracks:repeat(2,minmax(0,1fr));grid-template-columns:var(--tracks)}.card{min-width:0}.url{overflow-wrap:anywhere}
驗收證據
runtime before=`1fr 1fr`、after=`minmax(0,1fr) minmax(0,1fr)`、property=--tracks;人工證據為 scrollWidth<=clientWidth
常混淆
min-content 是內容能在合法斷點下縮到的最小內在尺寸,不等於 CSS min-width 的固定數值。

Micro Lab|min-content 與長字串溢位

情境:兩欄服務 Grid 在手機出現水平捲軸,問題卡片含一串不可斷的預約代碼。

起始狀態:--tracks 為 1fr 1fr;長 token 已可辨識,尚未使用安全最小軌道。

  1. 執行實驗切換 safe-grid-tracks class,讀取實際控制 grid-template-columns 的 --tracks custom property。
  2. 執行下方操作,觀察獨立的 DOM 與資料狀態。
  3. 依證據欄位重新驗收。

目前主題:min-content 與長字串溢位

service-reference-2026-very-long-unbroken-token
摘要
尚未執行;DOM data-state=starter。

預期:runtime 的 --tracks 由 `1fr 1fr` 變 `minmax(0,1fr) minmax(0,1fr)`;人工重測 Grid 不再橫向溢位。

證據:runtime before=`1fr 1fr`、after=`minmax(0,1fr) minmax(0,1fr)`、property=--tracks;人工證據為 scrollWidth<=clientWidth

第一個檢查:先讀 Grid 與長 token 的 scrollWidth/clientWidth,再檢查 grid-template-columns。

重設:重新載入 module,移除 safe-grid-tracks class。

卡住時

  • 症狀:track 已用 minmax(0,1fr),文字仍穿出卡片。
    可能原因:軌道可縮,但長 token 本身仍沒有 break opportunity。
    先檢查:比較卡片 clientWidth 與文字 scrollWidth,讀 overflow-wrap。
    修正:保留安全 tracks,對長 token 加 overflow-wrap:anywhere。

理解檢查

`minmax(0,1fr)` 中的 0 解決什麼?

尚未作答。

查看解釋

0 是最小 track sizing function;1fr 仍負責最大彈性分配。

本模組官方來源:MDN|minmax()

5. Grid 軌道、區域與內容尺寸|整合 Lab

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

交付:完成具命名區域、隱式列與長內容安全的 Grid 版面。

尚未執行整合步驟。
  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

    操作:執行實驗替三 item grid 切換 size-implicit-row class,讀取 computed grid-auto-rows。 → 執行實驗替 Grid container 切換 named-areas class,讀取 computed grid-template-areas。 → 執行實驗替推薦 item 切換 align-featured-end class,讀取 computed align-self。 → 執行實驗切換 safe-grid-tracks class,讀取實際控制 grid-template-columns 的 --tracks custom property。

    // 09-01-explicit-implicit-tracks: 執行實驗替三 item grid 切換 size-implicit-row class,讀取 computed grid-auto-rows。
    // 09-02-grid-template-areas: 執行實驗替 Grid container 切換 named-areas class,讀取 computed grid-template-areas。
    // 09-03-grid-item: 執行實驗替推薦 item 切換 align-featured-end class,讀取 computed align-self。
    // 09-04-min-content: 執行實驗切換 safe-grid-tracks class,讀取實際控制 grid-template-columns 的 --tracks custom property。

    預期:完成具命名區域、隱式列與長內容安全的 Grid 版面。

    證據:runtime before=auto、after=56px、property=grid-auto-rows;DOM item count=3,模板容量第一列只有2項;runtime before=none;after 包含 "header header" 與 "sidebar main";property=grid-template-areas;runtime before=auto、after=end、property=align-self;其他 item computed align-self 仍為 auto;runtime before=`1fr 1fr`、after=`minmax(0,1fr) minmax(0,1fr)`、property=--tracks;人工證據為 scrollWidth<=clientWidth

    原因:逐項整合能把回歸定位到明確 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

    操作:替另一個商家情境重做,仍達成:完成具命名區域、隱式列與長內容安全的 Grid 版面。

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

    預期:完成具命名區域、隱式列與長內容安全的 Grid 版面。

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

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

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

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

6. 自學挑戰與三層提示

挑戰:將同一組責任轉用到另一個商家情境,仍達成:完成具命名區域、隱式列與長內容安全的 Grid 版面。

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

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

提示 1|方向提示

拆小:在「Grid 軌道、區域與內容尺寸」先完成第一個尚未通過的 module:explicit 與 implicit tracks,不同時修改其他責任。

提示 2|關鍵片段

串接:依 09-01-explicit-implicit-tracks → 09-02-grid-template-areas → 09-03-grid-item → 09-04-min-content 核對各自輸入與證據。

提示 3|完整解答與原因

完整解答與原因:依序執行 執行實驗替三 item grid 切換 size-implicit-row class,讀取 computed grid-auto-rows。 → 執行實驗替 Grid container 切換 named-areas class,讀取 computed grid-template-areas。 → 執行實驗替推薦 item 切換 align-featured-end class,讀取 computed align-self。 → 執行實驗切換 safe-grid-tracks class,讀取實際控制 grid-template-columns 的 --tracks custom property。;這個順序能把每個結果對回單一 module,避免整合後無法定位。

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

7. 症狀式除錯指南

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

哪個狀態代表 09-01-explicit-implicit-tracks 完成?

尚未作答。

查看解釋

資料筆數增加時,implicit rows 會真實參與版面;若只看模板欄數,容易誤判新增卡片的高度與位置。

哪個狀態代表 09-02-grid-template-areas 完成?

尚未作答。

查看解釋

area 名稱比匿名 line number 更能傳達版面意圖;非矩形或拼字不一致會使整個 template declaration 無效。

哪個狀態代表 09-03-grid-item 完成?

尚未作答。

查看解釋

把 self 規則寫在容器或把 items 規則寫在 item,會讓對齊看似無效並引發多餘的 position/margin 修補。

哪個狀態代表 09-04-min-content 完成?

尚未作答。

查看解釋

Grid 的 1fr 軌道仍可能受 min-content 撐寬;只隱藏 overflow 會裁掉內容,無法修正 track sizing 根因。

驗收清單

官方來源

回到課程地圖選擇下一章