LESSON-09 · 零基礎學生教材
CSS 進階:Grid 服務型商家版面骨架
完成服務頁的 Grid 骨架,主服務卡與其他卡片在寬度改變時仍保持合理比例。
先理解:這堂課解決什麼問題?
首頁服務資訊開始增加,單純 Flexbox 不容易表達主卡片與側邊資訊的二維關係。
本堂要完成:完成服務頁的 Grid 骨架,主服務卡與其他卡片在寬度改變時仍保持合理比例。
學習邊界:先完成「用 CSS Grid 建立可伸縮的服務型商家版面」,不提前引入尚未教過的框架或建置工具。
先備知識與操作環境
本堂先備:首頁服務資訊開始增加,單純 Flexbox 不容易表達主卡片與側邊資訊的二維關係。 需要的檔案是 index.html、.service-grid、.service-card--featured、style.css。若尚未理解這些位置,先開啟 README 的最小實驗,再開始階段練習。
- 檔案位置:先找到
index.html、.service-grid、.service-card--featured、style.css,再從本頁的最小實驗開始。 - 瀏覽器:開啟最小實驗與階段頁;每次修改後儲存並重新整理。
- DevTools:依本堂內容使用 Elements、Styles、Computed、Console 或 Network,記下第一個可觀察證據。
- 操作習慣:每次只修改一個檔案或一個責任,先預測、再操作、最後驗收。
先做最小實驗:先看見結果
這不是期末網站,而是一個可以直接看到本堂核心結果的最小實驗。先完成一次操作,再回到檔案和名詞卡對照。
- 入口:開啟
examples/minimal.html。 - 操作:開啟
examples/minimal.html,先用桌機寬度觀察 Grid overlay,再切到約 390px;不要修改這份最小實驗。 - 預期:桌機有多欄、推薦卡跨滿一列;窄版欄數減少且沒有水平捲軸。Computed 能讀到 display:grid、grid-template-columns 與 gap。
- 重設:重新整理
examples/minimal.html,或關閉 DevTools 暫時修改;這份檔案只用來觀察,不要當成 Starter 修改。
學生練習流程
依序完成每一張卡;目前只聚焦一個步驟,先操作,再用可觀察證據確認結果。
-
1
最小實驗
先開啟examples/minimal.html,用桌機寬度觀察四張服務卡;再切到約 390px,記下欄數與是否有水平捲軸。 -
2
名詞
回到名詞卡,依序拆解 CSS Grid、Grid container、Grid item、track、Grid line、fr、repeat()、minmax()、auto-fit、gap與grid-column。 -
3
Starter
把 Starter 複製到自己的工作資料夾,依五張微步驟卡完成:先建立 HTML 父子結構,再建立 Grid、加入 gap、改成流動欄位,最後讓推薦卡跨欄;每一步都先預測再重新整理。 -
4
Step 4
每完成一張卡,就在 Elements 選取.service-grid,從 Computed 和 Grid overlay 確認目前的父層、欄位、tracks、lines 與 item 位置。 -
5
Checkpoint
前往 Checkpoint,在約 390px 重現固定欄寬造成的水平捲軸;先比較scrollWidth與clientWidth,再只修正style.css的 CHECKPOINT-1。 -
6
Solution
前往 Solution,逐檔對照完整 HTML/CSS;最後用桌機、約 390px、Grid overlay、Computed 與水平寬度數值留下驗收證據,並閱讀下一堂銜接:下一堂再把這個 Grid 骨架交給響應式規則,決定不同可用寬度下何時增加欄位。
檔案地圖:每個位置負責什麼?
先不要急著背檔名;請把檔案位置和責任連起來。你在階段頁會看到同一份檔案的可執行版本。
index.html首頁入口:呈現商家第一印象與主要 CTA。.service-grid服務 Grid class:控制服務卡片的列欄與間距。.service-card--featured推薦服務卡:作為 Grid item 跨滿一整列的服務卡片。style.cssCSS 樣式檔:放置本堂「用 CSS Grid 建立可伸縮的服務型商家版面」相關的版面規則。
先學會這些詞
先從名詞、英文與白話意思開始;每次只展開一張名詞卡,再對照正式定義、範例與驗收證據。專業術語、語法、檔案路徑會使用不同樣式。第一次遇到術語時,先回到這裡,不要靠猜。
Grid 基礎
9 個詞CSS GridCSS Grid Layout 白話意思:用列和欄一起安排頁面內容的 CSS 版面系統。 展開查看正式定義、範例與驗收證據
- 正式定義
- 以 grid container 建立二維軌道,讓直接子元素依列、欄與間距排列。
- 什麼時候用
- 服務卡片同時需要處理橫向欄位與縱向列時。
- 最小範例
- .service-grid { display: grid; } 讓父層開始使用 Grid 排版。
- 可觀察證據
- 畫面排列、Computed 的 display,以及 DevTools Grid overlay。
- 容易混淆
- 和 Flexbox 混淆;本堂先處理列欄的二維關係,不把所有問題都交給 margin。
Grid containerGrid container 白話意思:負責安排子元素列欄的父層。 展開查看正式定義、範例與驗收證據
- 正式定義
- 設定
display: grid的元素;它的直接子元素會依 Grid 軌道排列。 - 什麼時候用
- 要讓多張服務卡由同一個父層控制欄數與間距時。
- 最小範例
- <div class="service-grid"> 包住多個 .service-card。
- 可觀察證據
- Elements 往上找到
.service-grid,Computed 讀到display: grid。 - 容易混淆
- 和 Grid item 混淆;container 是父層,item 是它的直接子元素。
Grid itemGrid item 白話意思:被 Grid 父層安排位置的直接子元素。 展開查看正式定義、範例與驗收證據
- 正式定義
- Grid container 的直接子元素;它可以依欄線指定自己的 placement。
- 什麼時候用
- 要確認哪一些元素會被 Grid 排版,或讓推薦卡跨欄時。
- 最小範例
- .service-grid 裡的每個 <article class="service-card"> 都是 Grid item。
- 可觀察證據
- Elements 數出直接子元素,Grid overlay 顯示每個 item 的位置。
- 容易混淆
- 和任意後代元素混淆;只有直接子元素自動成為 Grid item。
trackGrid track 白話意思:Grid 裡的一條欄或一列。 展開查看正式定義、範例與驗收證據
- 正式定義
- 由兩條相鄰 Grid line 所界定的 column track 或 row track。
- 什麼時候用
- 要說明卡片落在哪一欄、哪一列,而不是只描述畫面位置時。
- 最小範例
- repeat(3, 1fr) 會建立三條 column track。
- 可觀察證據
- Grid overlay 標出欄線與軌道,Computed 顯示欄位的計算寬度。
- 容易混淆
- 和 Grid line 混淆;track 是兩條線之間的空間,line 是邊界。
Grid lineGrid line 白話意思:分隔 Grid 欄或列的編號線。 展開查看正式定義、範例與驗收證據
- 正式定義
- Grid layout 用來界定 track 起點與終點的虛擬線;編號從 1 開始。
- 什麼時候用
- 要讓一個 Grid item 跨過多欄或指定起訖位置時。
- 最小範例
- grid-column: 1 / -1 從第一條欄線跨到最後一條欄線。
- 可觀察證據
- Grid overlay 的線號、推薦卡的起始與結束位置。
- 容易混淆
- 和 border 線混淆;Grid line 是版面計算概念,不一定會畫成可見邊框。
grid-template-columnsgrid-template-columns 白話意思:決定 Grid 有哪些欄,以及每欄多寬。 展開查看正式定義、範例與驗收證據
- 正式定義
- 明確定義 Grid container column tracks 尺寸與重複模式的 CSS property。
- 什麼時候用
- 要從一欄改成三欄,或讓欄位依可用寬度流動時。
- 最小範例
- grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));。
- 可觀察證據
- Computed 的欄位像素值、390px/桌機的欄數與 Grid overlay。
- 容易混淆
- 和
width混淆;width 是元素寬度,這個 property 決定父層的欄位結構。
frfractional unit 白話意思:把可用剩餘空間按比例分配的單位。 展開查看正式定義、範例與驗收證據
- 正式定義
- CSS Grid 專用的 fractional unit,依 track 間剩餘空間分配尺寸。
- 什麼時候用
- 不想把每欄鎖死成固定像素,而要讓欄位填滿容器時。
- 最小範例
- 1fr 1fr 把可用空間分成兩份。
- 可觀察證據
- 改變 viewport 後,Computed 欄位像素值會跟著改變。
- 容易混淆
- 和
px混淆;fr 是比例,不是固定長度。
repeat()repeat() function 白話意思:用短寫法重複建立相同的欄位規則。 展開查看正式定義、範例與驗收證據
- 正式定義
- CSS Grid 的 track-list
function,將指定的 track pattern 重複固定次數或依條件重複。 - 什麼時候用
- 多欄規則相同,或需要搭配 auto-fit 重複可用欄位時。
- 最小範例
- repeat(3, minmax(0, 1fr)) 表示重複三次同樣的欄位規則。
- 可觀察證據
- Computed 欄位數量、Grid overlay 欄線與窄版換列結果。
- 容易混淆
- 和 JavaScript 的迴圈混淆;repeat() 是 CSS 值語法,不會產生 HTML。
minmax()minmax() function 白話意思:為欄位設定最小和最大尺寸的函式。 展開查看正式定義、範例與驗收證據
- 正式定義
- CSS Grid track sizing
function,在最小值與最大值之間計算軌道尺寸。 - 什麼時候用
- 要讓卡片至少有可讀寬度,又能在較寬容器中伸展時。
- 最小範例
- minmax(220px, 1fr) 表示每欄至少 220px,剩餘空間可按比例分配。
- 可觀察證據
- 窄版欄數、卡片文字是否被擠壓,以及 Computed 欄位值。
- 容易混淆
- 和
clamp()混淆;本堂 minmax() 直接描述 Grid track,不是一般 property 的尺寸函式。
自動排列與跨欄
3 個詞auto-fitauto-fit keyword 白話意思:依容器目前可用寬度自動放入能容納的欄數。 展開查看正式定義、範例與驗收證據
- 正式定義
- Grid 的 auto-fit 重複模式;瀏覽器會依可用空間折疊沒有內容的欄位並重新分配空間。
- 什麼時候用
- 服務卡數量可能改變,且不想為每一種寬度手動寫欄數時。
- 最小範例
- repeat(auto-fit, minmax(220px, 1fr)) 會在寬版放多欄,窄版換成較少欄。
- 可觀察證據
- 拖曳 viewport 寬度時欄數改變、沒有水平捲軸、Grid overlay 重新排列。
- 容易混淆
- 和
auto-fill混淆;本堂先使用 auto-fit,觀察有內容欄位如何填滿可用空間。
gapgap 白話意思:Grid 欄與欄、列與列之間的共同間距。 展開查看正式定義、範例與驗收證據
- 正式定義
- 設定 layout container 內部 tracks 間距的 CSS property。
- 什麼時候用
- 需要讓所有服務卡保持一致空隙時。
- 最小範例
- .service-grid { gap: 1rem; }。
- 可觀察證據
- Computed 讀到 gap,卡片間距一致且不需要逐張加 margin。
- 容易混淆
- 和 padding 混淆;gap 在子元素之間,padding 在容器內邊界。
grid-columngrid-column 白話意思:指定 Grid item 從哪條欄線排到哪條欄線。 展開查看正式定義、範例與驗收證據
- 正式定義
- 控制 Grid item column-start 與 column-end placement 的 CSS shorthand property。
- 什麼時候用
- 推薦卡需要跨滿一整列,或某個 item 要佔據特定欄位時。
- 最小範例
- .service-card--featured { grid-column: 1 / -1; }。
- 可觀察證據
- Grid overlay 的起訖線、推薦卡是否跨滿整列。
- 容易混淆
- 和
grid-template-columns混淆;前者安排單一 item,後者定義父層欄位。
尺寸與驗收
3 個詞viewportviewport 白話意思:瀏覽器目前拿來顯示頁面的可視範圍。 展開查看正式定義、範例與驗收證據
- 正式定義
- 使用者代理程式呈現文件內容的視窗區域;本堂用它測試 Grid 可用寬度。
- 什麼時候用
- 要比較 390px 與桌機欄數、卡片可讀性和水平溢位時。
- 最小範例
- DevTools 裝置模式設為 390px,就是在觀察 390px viewport。
- 可觀察證據
- 目前 viewport 寬度、畫面欄數與 Grid overlay。
- 容易混淆
- 和整個瀏覽器視窗混淆;viewport 是頁面內容實際可見的範圍。
overflowoverflow 白話意思:內容超出容器或 viewport 邊界的狀態。 展開查看正式定義、範例與驗收證據
- 正式定義
- 內容盒超出可用排版區域時形成的版面溢位。
- 什麼時候用
- 固定欄寬在手機造成水平捲軸時。
- 最小範例
- repeat(3, 220px) 在窄 viewport 可能讓三欄總寬超過容器。
- 可觀察證據
- 水平捲軸,以及
scrollWidth大於clientWidth。 - 容易混淆
- 和
overflow-x: hidden混淆;隱藏捲軸不等於修正固定欄寬的根因。
Grid overlayGrid overlay 白話意思:DevTools 疊在頁面上的 Grid 輔助線。 展開查看正式定義、範例與驗收證據
- 正式定義
- 瀏覽器開發者工具用來標示 Grid container、tracks、lines 與 items 的視覺化檢查功能。
- 什麼時候用
- 看不懂卡片為什麼換列,或需要確認跨欄是否真的生效時。
- 最小範例
- 在 Elements 選取 .service-grid,開啟 Grid badge/overlay。
- 可觀察證據
- 畫面上看得到欄線、列線、track 編號與 item 邊界。
- 容易混淆
- 和畫面上的 border 混淆;overlay 是 DevTools 的暫時觀察輔助,不是網站內容。
最小例子:先看懂,再複製
這段只保留本堂第一個微成果。先預測結果,再逐行讀;完整檔案請開啟下方最小實驗。
Elements:section > .service-grid > 4 個 .service-card
<div class="service-grid">
<article class="service-card">...</article>
</div>Live Lab:逐段讀碼與驗證
每一步只回答五件事:為什麼做、改哪裡、會看到什麼、用什麼證據確認、卡住先查什麼。
-
Step 1
先在 HTML 分清楚 container 與 item
- 目的
- 先建立 Grid 的父子關係,讓後面的 CSS 有真正可以排列的直接子元素。
- 修改位置
starter/files/index.html的 service-section
在 service-section 放入一個 service-grid,並讓四個 article 成為它的直接子元素。- 預期結果
- Elements 能展開一個 service-grid,並數出四個直接子層 service-card;此時先不期待多欄。
- 驗收證據
- Elements 的 DOM 階層、service-grid 的直接子元素數量與 HTML 檔案位置。
- 卡住先查
- 只檢查 service-grid 是否包住四個 article,以及每張卡是否有 service-card class。
-
Step 2
讓父層成為 Grid container
- 目的
- 先用 display:grid 和明確欄位看見 tracks,而不是用 margin 假裝排列。
- 修改位置
starter/files/style.css的.service-grid
在.service-grid設定 display:grid 與 repeat(3, minmax(0, 1fr))。- 預期結果
- 桌機畫面出現三欄;DevTools Grid overlay 能標出欄線與每張卡的 Grid item 邊界。
- 驗收證據
- 選取
.service-grid,Computed 有 display:grid 與 grid-template-columns;Grid overlay 顯示三條欄軌道。 - 卡住先查
- 先確認選取的是父層
.service-grid,不要先檢查單張.service-card。
-
Step 3
用 gap 管理列欄間距
- 目的
- 把共同的卡片間距交給父層,分清楚 gap 和每張卡自己的 margin。
- 修改位置
starter/files/style.css的.service-grid
在.service-grid加入 gap: 1rem。- 預期結果
- 欄與列之間有一致間距;Computed 讀到 16px 左右的 gap。
- 驗收證據
- 畫面卡片間距、
.service-grid的 Computed gap,以及 Grid overlay 的 track 間隔。 - 卡住先查
- 只檢查
.service-grid的 gap 宣告是否命中;不要先改卡片 margin。
-
Step 4
用 auto-fit 與 minmax 讓欄位流動
- 目的
- 讓欄位至少保留卡片可讀寬度,再由剩餘空間決定欄數與每欄比例。
- 修改位置
starter/files/style.css的 grid-template-columns
把欄位改為 repeat(auto-fit, minmax(220px, 1fr)),再用 390px 和桌機各測一次。- 預期結果
- 桌機保留多欄;390px 會減少欄數,服務卡可讀且頁面沒有水平捲軸。
- 驗收證據
- 390px/桌機欄數、Computed 欄位像素值、Grid overlay,以及 scrollWidth 與 clientWidth 比較。
- 卡住先查
- 先在 390px 找
.service-grid的 Computed grid-template-columns,再確認是否仍有三個固定 220px。
-
Step 5
用 grid-column 讓推薦卡跨滿一列
- 目的
- 用 Grid line 表達主卡片的版面責任,不靠負 margin 或移動 HTML 位置。
- 修改位置
starter/files/style.css的.service-card--featured
加入 grid-column: 1 / -1,觀察它從第一條欄線跨到最後一條欄線。- 預期結果
- 推薦卡在 Grid overlay 中跨滿一列,其他卡片仍由父層自動排列。
- 驗收證據
- Grid overlay 的起始/結束線、推薦卡的位置與 Elements 中它仍是 service-grid 直接子元素。
- 卡住先查
- 先確認 HTML 的 class 真的包含 service-card--featured,再看 selector 是否命中。
-
Step 6
用數值證據修正固定欄寬
- 目的
- 從真實水平溢位回到 grid-template-columns,而不是用 overflow 隱藏症狀。
- 修改位置
checkpoint/files/style.css的 CHECKPOINT-1
先比較 document.documentElement.scrollWidth 與 clientWidth,再把固定欄寬改回 auto-fit、minmax 與 1fr。- 預期結果
- 修正前可重現水平捲軸;修正後 scrollWidth 不大於 clientWidth,Grid overlay 顯示可用欄數。
- 驗收證據
- 修正前後的 scrollWidth/clientWidth、Computed 欄位、390px 畫面與 Grid overlay。
- 卡住先查
- 只檢查
.service-grid的 grid-template-columns;先不要改 page-shell 或 body 的 overflow。
讀碼順序:先找入口,再找被引用的檔案,最後用畫面、DOM、Console、Network 或資料結果驗證。
互動問答
先回答目前這一題,再展開解析;完成後按下一題,讓每一次回答都回到檔案或瀏覽器完成驗證。
Q1概念理解 「CSS Grid(CSS Grid Layout)」在本堂要解決什麼問題? 本題線索:CSS Grid;回到名詞卡與 畫面排列、Computed 的 display,以及 DevTools Grid overlay。 展開解析收合解析
白話解析:
用列和欄一起安排頁面內容的 CSS 版面系統。 正式來說,以 grid container 建立二維軌道,讓直接子元素依列、欄與間距排列。
對照位置:
回到名詞卡「CSS Grid」,再看 畫面排列、Computed 的 display,以及 DevTools Grid overlay。
預期觀察:
你應該能用自己的話說出:服務卡片同時需要處理橫向欄位與縱向列時。
常見錯誤:
不要只回答「它是CSS Grid」;那是重複名詞,不是說明責任。
立即驗證:
開啟 examples/minimal.html,依序做「開啟 examples/minimal.html,先用桌機寬度觀察 Grid overlay,再切到約 390px;不要修改這份最小實驗。」並記下畫面或工具證據。
Q2程式碼閱讀
修改指定規則後,你預測畫面會看到什麼?
本題線索:starter/files/index.html 的 service-section;要修改:在 service-section 放入一個 service-grid,並讓四個 article 成為它的直接子元素。;觀察:Elements 的 DOM 階層、service-grid 的直接子元素數量與 HTML 檔案位置。
展開解析收合解析
白話解析:
先看檔案責任,再預測結果。這一步的目的:先建立 Grid 的父子關係,讓後面的 CSS 有真正可以排列的直接子元素。
對照位置:
對照 Live Lab Step 1,位置是 starter/files/index.html 的 service-section;範例內容:Elements:section > .service-grid > 4 個 .service-card
<div class="service-grid">
<article class="service-card">...</article>
</div>
預期觀察:
Elements 能展開一個 service-grid,並數出四個直接子層 service-card;此時先不期待多欄。
常見錯誤:
如果只改了檔案但沒有結果,先不要重寫全部;只檢查 service-grid 是否包住四個 article,以及每張卡是否有 service-card class。
立即驗證:
實際操作後檢查 Elements 的 DOM 階層、service-grid 的直接子元素數量與 HTML 檔案位置。。
Q3概念比較
「CSS Grid」和「Grid container」在本堂的責任有什麼不同?
本題線索:比較 CSS Grid 與 Grid container;操作位置:starter/files/style.css 的 .service-grid
展開解析收合解析
白話解析:
CSS Grid:用列和欄一起安排頁面內容的 CSS 版面系統。;Grid container:負責安排子元素列欄的父層。
對照位置:
對照兩張名詞卡的正式定義:以 grid container 建立二維軌道,讓直接子元素依列、欄與間距排列。/設定 display: grid 的元素;它的直接子元素會依 Grid 軌道排列。
預期觀察:
你應該能指出兩者分別出現在哪個檔案或工具,以及哪一個結果會改變。
常見錯誤:
不要把「改變畫面」當成所有技術的責任;先說清楚誰負責結構、呈現、行為或驗收。
立即驗證:
在 starter/files/style.css 的 .service-grid 做「在 .service-grid 設定 display:grid 與 repeat(3, minmax(0, 1fr))。」,再用 選取 .service-grid,Computed 有 display:grid 與 grid-template-columns;Grid overlay 顯示三條欄軌道。 比較前後差異。
Q4除錯驗收
如果完成操作後結果不對,你會先從哪一個證據開始查?
本題線索:checkpoint/files/style.css 的 CHECKPOINT-1;第一個檢查位置:修正前後的 scrollWidth/clientWidth、Computed 欄位、390px 畫面與 Grid overlay。
展開解析收合解析
白話解析:
先描述症狀,再提出一個最小假設。本堂常見錯誤是:加 overflow-x:hidden,讓捲軸消失但固定欄位仍然超出內容區。
對照位置:
對照最後一段 Live Lab:checkpoint/files/style.css 的 CHECKPOINT-1;檢查方式:只檢查 .service-grid 的 grid-template-columns;先不要改 page-shell 或 body 的 overflow。
預期觀察:
你要能指出一個具體位置,而不是一次修改很多檔案。
常見錯誤:
不要先清快取、重裝工具或複製 Solution;先查看第一個可觀察錯誤。
立即驗證:
重新操作並留下「症狀、證據、假設、單一修正、結果」五項紀錄。
常見誤解
- 看到畫面沒有變化,不代表程式沒執行;先確認檔案、路徑、元素與狀態證據。
- 能複製 Solution 不代表理解;請先說出修改哪個檔案、預期哪個結果、用什麼證據確認。
- 本堂只使用 HTML、CSS、瀏覽器與 DevTools;先完成 Grid 的父子關係、欄位、間距與跨欄,不加入 JavaScript、框架、建置工具或其他版面主題。
本堂任務與驗收
完成服務頁的 Grid 骨架,主服務卡與其他卡片在寬度改變時仍保持合理比例。
- 能用 Grid overlay 留下可重現證據。
- 能用 欄數 留下可重現證據。
- 能用 gap 留下可重現證據。
- 能用 featured 跨欄 留下可重現證據。
- 能用 390px 可讀性與無水平捲軸 留下可重現證據。
- Starter、Checkpoint、Solution 的入口都能開啟並知道三者差異。
- 遇到問題時能先寫出症狀,再檢查一個最小假設。