商用網站架設實務

LESSON-11 · 零基礎學生教材

CSS 進階:Position、Sticky 與堆疊

完成推薦徽章、可捲動的 sticky 頁首與 fixed 聯絡入口;重疊層級清楚,窄版與鍵盤焦點不被遮住。

先理解:這堂課解決什麼問題?

商家希望在服務頁標出推薦方案,並讓聯絡入口在長頁面中保持可找到。

本堂要完成:完成推薦徽章、可捲動的 sticky 頁首與 fixed 聯絡入口;重疊層級清楚,窄版與鍵盤焦點不被遮住。

學習邊界:先完成「用 Position 控制元素參考點、捲動行為與前後層級」,不提前引入尚未教過的框架或建置工具。

第一次上課環境:先理解瀏覽器、CSS 與證據

  1. 瀏覽器:開啟 examples/01-flow-relative.html;瀏覽器會讀 HTML、套用 CSS,建立你看到的畫面。
  2. 檔案:本堂只使用 index.htmlstyle.cssexamples/;不需要 npm、框架或 JavaScript。
  3. DevTools:在頁面按右鍵選「檢查」,Elements 看 HTML 階層,Styles 看命中的規則,Computed 看瀏覽器最後採用的 position、top、z-index 與 overflow。
  4. 操作習慣:每次先預測,再只修改一個 selector;儲存、重新整理、捲動或按 Tab,最後用畫面與 DevTools 證明結果。

先做最小實驗:先看見結果

這不是期末網站,而是一個可以直接看到本堂核心結果的最小實驗。先完成一次操作,再回到檔案和名詞卡對照。

開啟本堂最小實驗

  1. 入口:開啟 examples/01-flow-relative.html
  2. 操作:依序開啟四個實驗:比較 normal flowrelative,暫時移除 containing blockrelative,捲動 sticky,最後捲動 fixed 頁面並用 Tab 走過連結與按鈕。
  3. 預期:四個檔案都能直接開啟;relative 保留原空間、absolute badge 跟著 card、sticky 有足夠內容可捲動、fixed CTA 不遮住最後內容,兩張重疊卡片可比較 z-index
  4. 重設:重新開啟 examples/01-flow-relative.htmlDevTools 暫時修改只要重新整理即可清除。

學生練習流程

依序完成每一張卡;目前只聚焦一個步驟,先操作,再用可觀察證據確認結果。

  1. 1

    名詞

    先閱讀檔案地圖與名詞卡,說出 normal flow、viewport、containing block 與 z-index 的白話意思。
  2. 2

    驗收

    依序開啟 examples/01-flow-relative.htmlexamples/04-fixed-z-index-focus.html;每個實驗都完成「目的 → 操作 → 預期結果 → DevTools 證據 → 卡住時檢查」。
  3. 3

    Starter

    把 Starter 複製到自己的資料夾,依四張微步驟卡完成:relative、absolute badge、sticky、fixed/z-index/focus;每次只修改一個檔案責任。
  4. 4

    Checkpoint

    前往 Checkpoint,先預測 badge 沒有 relative 父層時的 containing block,再在 style.css 修正唯一的 CHECKPOINT-1。
  5. 5

    Solution

    前往 Solution,逐檔對照完整 absolute、sticky、fixed、z-index、底部留白與 focus-visible;用 390px、桌機、200% 文字與純 Tab 完成最後驗收。
  6. 6

    變體驗收

    完成情境變體與獨立挑戰,留下檔案位置、操作、預期結果、實際觀察與截圖/Computed 證據,並閱讀下一堂銜接:狀態與無障礙:下一堂會把 focus、hover 與表單錯誤狀態整理成可操作的介面回饋。

檔案地圖:每個位置負責什麼?

先不要急著背檔名;請把檔案位置和責任連起來。你在階段頁會看到同一份檔案的可執行版本。

先學會這些詞

先從名詞、英文與白話意思開始;每次只展開一張名詞卡,再對照正式定義、範例與驗收證據。專業術語語法檔案路徑會使用不同樣式。第一次遇到術語時,先回到這裡,不要靠猜。

本堂 13 個詞先選一組,再展開需要的名詞卡;每次只保留目前的學習焦點。

定位基礎

6 個詞
normal flownormal flow 白話意思:瀏覽器沒有額外定位時,元素依 HTML 順序自然排列。 展開查看正式定義、範例與驗收證據
正式定義
文件中未被特殊定位方式移出的元素,依區塊與行內排版規則佔據原本空間的排列方式。
什麼時候用
要先預測元素原本會在哪裡,或比較 relative 是否保留空間時。
最小範例
兩張卡片依序出現;前一張改變外觀不會讓後一張消失。
可觀察證據
Elements 順序、畫面位置,以及第二張卡片是否仍從原本位置開始。
容易混淆
viewport 混淆;normal flow 是文件內的排列規則,不是視窗座標。
staticposition: static 白話意思:元素使用瀏覽器預設的普通排列方式。 展開查看正式定義、範例與驗收證據
正式定義
position 的預設值;元素留在 normal flow 中,top、right、bottom、left 不會移動它。
什麼時候用
不需要特殊定位,只想讓元素依內容順序排列時。
最小範例
.flow-card { position: static; }
可觀察證據
Computedpositionstatic,設定 top 後畫面仍不位移。
容易混淆
relative 混淆;relative 會接受 offset,static 不會。
relativeposition: relative 白話意思:先留在原本位置,再從原位做小幅位移。 展開查看正式定義、範例與驗收證據
正式定義
元素仍占據 normal flow 原本的空間,但可依 offset properties 相對自身原位置移動;也能成為 absolute 子元素的 containing block
什麼時候用
要微調元素,或要讓卡片成為徽章的定位參考時。
最小範例
.service-card { position: relative; }
可觀察證據
卡片移動後原空間仍存在;子層 badge 以卡片角落為參考。
容易混淆
absolute 混淆;relative 保留自己的流內空間,absolute 通常不保留。
absoluteposition: absolute 白話意思:把元素從普通排列中拿出來,放到指定參考盒子的座標。 展開查看正式定義、範例與驗收證據
正式定義
元素不再占據 normal flow 的空間,位置通常相對最近的 positioned ancestor;若沒有,則繼續尋找更高層的 containing block
什麼時候用
徽章、裝飾或卡片內的角標需要貼在父層角落時。
最小範例
.featured-badge { position: absolute; top: .75rem; right: .75rem; }
可觀察證據
badge 不會把標題往下推,並隨 relative card 一起移動。
容易混淆
fixed 混淆;absolute 的參考可由祖先元素改變,fixed 通常以 viewport 為參考。
containing blockcontaining block 白話意思:定位元素拿來計算 top、right、bottom、left 的參考盒子。 展開查看正式定義、範例與驗收證據
正式定義
瀏覽器依定位方式與祖先建立的幾何區域,決定 positioned descendant 的尺寸與 offset 計算基準。
什麼時候用
absolute badge 跑到頁面角落,或不知道 top/right 是相對誰計算時。
最小範例
.service-card { position: relative; } .featured-badge { position: absolute; top: 0; right: 0; }
可觀察證據
Elements 的祖先關係、Computed position,以及 badge 是否貼在 card 右上角。
容易混淆
和 parent element 混淆;父元素不一定自動成為 containing block,通常要有適合的定位條件。
offset propertiestop / right / bottom / left 白話意思:告訴定位元素要離參考盒子的哪一側多遠。 展開查看正式定義、範例與驗收證據
正式定義
用於 positioned element 的偏移屬性;它們的實際效果取決於 positioncontaining block
什麼時候用
需要把 relative 元素移一點,或把 absolute badge 貼到角落時。
最小範例
.flow-card--moved { position: relative; top: 1rem; left: 1rem; }
可觀察證據
Computed 可看到 top/left,畫面可看到元素位移;static 元素不會因它們移動。
容易混淆
和 margin 混淆;offset 改變定位座標,margin 參與盒子間距與流動排版。

黏附與固定

3 個詞
stickyposition: sticky 白話意思:元素先在普通位置,捲到門檻後黏在指定位置。 展開查看正式定義、範例與驗收證據
正式定義
normal flow 中保留空間,並在接近指定 inset(例如 top: 0)時於其 scrolling ancestor 範圍內保持可見。
什麼時候用
長頁面的頁首或分段標題要在捲動時暫時留在視線內時。
最小範例
.site-header { position: sticky; top: 0; z-index: 10; }
可觀察證據
捲動前 header 在頁面原位,捲動後 header 停在 viewport 上方附近;Computed 仍是 sticky
容易混淆
fixed 混淆;sticky 受祖先與捲動範圍限制,fixed 通常不占流內空間且跟著 viewport
fixedposition: fixed 白話意思:元素固定在瀏覽器視窗的位置,捲動內容時仍留在那裡。 展開查看正式定義、範例與驗收證據
正式定義
元素從 normal flow 移出,通常相對 viewport 定位;它不會替後面的內容保留空間。
什麼時候用
聯絡 CTA、客服按鈕或需要一直可找到的操作入口時。
最小範例
.floating-contact { position: fixed; right: 1rem; bottom: 1rem; }
可觀察證據
捲動前後 CTA 都靠近視窗右下角,頁面內容另外用 padding-bottom 避免被遮住。
容易混淆
sticky 混淆;fixed 不會在某個流內自然停止,也不會自動替內容讓位。
viewportviewport 白話意思:瀏覽器目前用來顯示網頁的可視範圍。 展開查看正式定義、範例與驗收證據
正式定義
使用者代理程式呈現文件內容的視窗區域;fixed 元素通常以它作為定位參考。
什麼時候用
測試 fixed 位置、390px 窄版或 200% 文字放大時。
最小範例
在 DevTools 裝置模式切到 390px,再觀察 fixed CTA 的 right/bottom。
可觀察證據
視窗寬度、document 是否出現水平捲軸,以及 CTA 是否仍可讀可按。
容易混淆
和整個 HTML 文件高度混淆;viewport 是目前看得到的視窗區域。

層疊與驗收

4 個詞
stacking contextstacking context 白話意思:瀏覽器用來決定一組元素前後層級的獨立堆疊範圍。 展開查看正式定義、範例與驗收證據
正式定義
元素在同一 stacking context 內依 stack level、z-index 與文件順序繪製;不同 context 不能只靠子元素 z-index 任意穿透。
什麼時候用
兩個元素真的重疊,卻不知道為什麼某一張卡片在前面時。
最小範例
.stack-demo { position: relative; } .stack-card--front { position: absolute; z-index: 2; }
可觀察證據
兩張卡片實際重疊,Computed 可看到 z-index,畫面能指出哪張在上層。
容易混淆
和單純 z-index 數字混淆;z-index 只在適當的 stacking context 比較,不是全頁絕對排名。
z-indexz-index 白話意思:同一堆疊範圍中,數字用來比較誰畫在前面。 展開查看正式定義、範例與驗收證據
正式定義
設定 positioned element 或特定 layout item 的 stack level;數值較高通常繪製在較低值前方。
什麼時候用
sticky header、fixed CTA 或兩張重疊卡片需要明確前後順序時。
最小範例
.stack-card--back { z-index: 1; } .stack-card--front { z-index: 2; }
可觀察證據
兩張有面積重疊的卡片中,Computed z-index 與可見遮蓋順序一致。
容易混淆
position 混淆;z-index 不會自己讓元素重疊,也不會取代定位宣告。
overflowoverflow 白話意思:內容超出元素盒子時,決定要顯示、捲動或裁切的設定。 展開查看正式定義、範例與驗收證據
正式定義
控制內容超過盒子尺寸時的呈現方式;某些 overflow/scrolling ancestor 也會影響 sticky 的觀察範圍。
什麼時候用
sticky 沒有如預期黏住,或 fixed/badge 被裁切時。
最小範例
.lesson-frame { overflow: visible; }
可觀察證據
Computedoverflow 值、實際捲動容器與元素是否被裁切。
容易混淆
和解決問題混淆;用 overflow:hidden 藏住溢位不等於修正定位根因。
focus-visible:focus-visible 白話意思:鍵盤操作時,讓目前被選到的連結或按鈕顯示清楚外框。 展開查看正式定義、範例與驗收證據
正式定義
當瀏覽器判斷焦點需要以可見方式呈現時套用的 CSS pseudo-class;它補足只測滑鼠 hover 的盲點。
什麼時候用
驗收 Tab 順序、固定 CTA 是否擋住焦點,或要保留清楚的鍵盤操作位置時。
最小範例
:focus-visible { outline: 3px solid #1d4ed8; outline-offset: 3px; }
可觀察證據
不使用滑鼠,只按 Tab;每個連結與按鈕都有清楚外框,且外框沒有被 fixed 元素遮住。
容易混淆
:hover 混淆;hover 依賴滑鼠,focus-visible 讓鍵盤使用者看得到目前位置。

最小例子:先看懂,再複製

這段只保留本堂第一個微成果。先預測結果,再逐行讀;完整檔案請開啟下方最小實驗。

.flow-card--moved {
  position: relative;
  top: 1rem;
  left: 1rem;
}

Live Lab:逐段讀碼與驗證

每一步只回答五件事:為什麼做、改哪裡、會看到什麼、用什麼證據確認、卡住先查什麼。

  1. Step 1

    比較 normal flowrelative

    目的
    先知道元素原本如何排列,再觀察 relative 位移不會拿走原本空間。
    修改位置
    examples/01-flow-relative.htmlstyle.css
    .flow-card--moved { position: relative; top: 1rem; left: 1rem; }
    預期結果
    第二張卡片視覺上往右下移動,但第三張卡片仍保留原本的排列位置。
    驗收證據
    ElementsDOM 順序、Computed position/top/left,以及第二、三張卡片的畫面位置。
    卡住先查
    只檢查 .flow-card--moved 是否命中,並確認頁面目前真的載入這個 HTML
  2. Step 2

    absolute badge 找到 containing block

    目的
    用推薦徽章理解 absolute 不在 normal flow,且會尋找最近的 positioned ancestor。
    修改位置
    index.htmlstyle.css
    .service-card { position: relative; } .featured-badge { position: absolute; top: .75rem; right: .75rem; }
    預期結果
    badge 貼在服務卡右上角,不推動標題;移動 card 時 badge 跟著 card。
    驗收證據
    Elements 的父子關係、Computedposition,以及 badge 與 card 的相對角落。
    卡住先查
    只查看 .featured-badge 最近的 .service-card 是否有 position: relative
  3. Step 3

    捲動觀察 sticky

    目的
    理解 sticky 先留在文件流,再在 top 門檻成立後黏住。
    修改位置
    style.cssindex.html
    .site-header { position: sticky; top: 0; z-index: 10; }
    預期結果
    捲動長頁面後 header 停在視窗上方;回到頂端時仍能回到原本的文件位置。
    驗收證據
    捲動前後畫面、Computed position: sticky、top: 0 與文件總高度。
    卡住先查
    先確認入口頁內容高度大於 viewport,再查看是否有祖先 overflow 改變捲動容器。
  4. Step 4

    完成 fixedz-indexfocus 驗收

    目的
    把固定 CTA、實際重疊的卡片與鍵盤焦點放在同一個可操作頁面中。
    修改位置
    index.htmlstyle.css
    .page-shell { padding-bottom: 6rem; } .stack-card--front { z-index: 2; } :focus-visible { outline: 3px solid #1d4ed8; outline-offset: 3px; }
    預期結果
    CTA 固定在 viewport 右下角但不遮內容;兩張重疊卡片有可比較的前後層級;Tab focus 清楚可見。
    驗收證據
    捲動前後位置、兩張卡片的 Computed z-index、390px/200% 文字畫面與 Tab focus 截圖。
    卡住先查
    先分三件事看:CTA 是否 fixed、內容是否有 padding-bottom、焦點元素是否是 a 或 button。
  5. Step 5

    整合本堂驗收證據

    目的
    把前面完成的修改放回本堂任務,確認不是只修好單一畫面。
    修改位置
    examples/01-flow-relative.html 與本堂驗收證據
    依序檢查 normal flowrelativeabsolute 包含區塊、sticky 捲動前後、fixed 遮蔽處理、z-index 重疊、390px/200% 文字與鍵盤 focus,只記錄一個實際觀察,不新增本堂以外的技術。
    預期結果
    完成推薦徽章、可捲動的 sticky 頁首與 fixed 聯絡入口;重疊層級清楚,窄版與鍵盤焦點不被遮住。
    驗收證據
    normal flowrelativeabsolute 包含區塊、sticky 捲動前後、fixed 遮蔽處理、z-index 重疊、390px/200% 文字與鍵盤 focus
    卡住先查
    先確認目前開啟的檔案名稱是 examples/01-flow-relative.html,並從導覽逐一開啟其餘三個檔案。
  6. Step 6

    完成最後回歸檢查

    目的
    用本堂的操作與驗收條件重跑一次,留下可以重現的結果。
    修改位置
    examples/01-flow-relative.html 與本堂驗收證據
    依序檢查 normal flowrelativeabsolute 包含區塊、sticky 捲動前後、fixed 遮蔽處理、z-index 重疊、390px/200% 文字與鍵盤 focus,只記錄一個實際觀察,不新增本堂以外的技術。
    預期結果
    完成推薦徽章、可捲動的 sticky 頁首與 fixed 聯絡入口;重疊層級清楚,窄版與鍵盤焦點不被遮住。
    驗收證據
    normal flowrelativeabsolute 包含區塊、sticky 捲動前後、fixed 遮蔽處理、z-index 重疊、390px/200% 文字與鍵盤 focus
    卡住先查
    先確認目前開啟的檔案名稱是 examples/01-flow-relative.html,並從導覽逐一開啟其餘三個檔案。
操作層級Live Lab 段落導覽:切換六個實驗步驟

讀碼順序:先找入口,再用畫面、ElementsStylesComputed、捲動前後與純 Tab 驗證;本堂不使用 JavaScript 載入訊息假裝證明 CSS 定位有效。

互動問答

先回答目前這一題,再展開解析;完成後按下一題,讓每一次回答都回到檔案或瀏覽器完成驗證。

Q1概念理解 normal flow」在本堂要解決什麼問題? 本題線索:normal flow;回到名詞卡與 Elements 順序、畫面位置,以及第二張卡片是否仍從原本位置開始。 展開解析收合解析

白話解析:

瀏覽器沒有額外定位時,元素依 HTML 順序自然排列。 正式來說,文件中未被特殊定位方式移出的元素,依區塊與行內排版規則佔據原本空間的排列方式。

對照位置:

回到名詞卡「normal flow」,再看 Elements 順序、畫面位置,以及第二張卡片是否仍從原本位置開始。

預期觀察:

你應該能用自己的話說出:要先預測元素原本會在哪裡,或比較 relative 是否保留空間時。

常見錯誤:

不要只回答「它是normal flow」;那是重複名詞,不是說明責任。

立即驗證:

開啟 examples/01-flow-relative.html,依序做「依序開啟四個實驗:比較 normal flowrelative,暫時移除 containing blockrelative,捲動 sticky,最後捲動 fixed 頁面並用 Tab 走過連結與按鈕。」並記下畫面或工具證據。

Q2程式碼閱讀 修改指定規則後,你預測畫面會看到什麼? 本題線索:examples/01-flow-relative.htmlstyle.css;要修改:.flow-card--moved { position: relative; top: 1rem; left: 1rem; };觀察:ElementsDOM 順序、Computed position/top/left,以及第二、三張卡片的畫面位置。 展開解析收合解析

白話解析:

先看檔案責任,再預測結果。這一步的目的:先知道元素原本如何排列,再觀察 relative 位移不會拿走原本空間。

對照位置:

對照 Live Lab Step 1,位置是 examples/01-flow-relative.htmlstyle.css;範例內容:.flow-card--moved { position: relative; top: 1rem; left: 1rem; }

預期觀察:

第二張卡片視覺上往右下移動,但第三張卡片仍保留原本的排列位置。

常見錯誤:

如果只改了檔案但沒有結果,先不要重寫全部;只檢查 .flow-card--moved 是否命中,並確認頁面目前真的載入這個 HTML

立即驗證:

實際操作後檢查 ElementsDOM 順序、Computed position/top/left,以及第二、三張卡片的畫面位置。。

Q3概念比較 normal flow」和「static」在本堂的責任有什麼不同? 本題線索:比較 normal flowstatic;操作位置:index.htmlstyle.css 展開解析收合解析

白話解析:

normal flow:瀏覽器沒有額外定位時,元素依 HTML 順序自然排列。;static:元素使用瀏覽器預設的普通排列方式。

對照位置:

對照兩張名詞卡的正式定義:文件中未被特殊定位方式移出的元素,依區塊與行內排版規則佔據原本空間的排列方式。/position 的預設值;元素留在 normal flow 中,top、right、bottom、left 不會移動它。

預期觀察:

你應該能指出兩者分別出現在哪個檔案或工具,以及哪一個結果會改變。

常見錯誤:

不要把「改變畫面」當成所有技術的責任;先說清楚誰負責結構、呈現、行為或驗收。

立即驗證:

index.htmlstyle.css 做「.service-card { position: relative; } .featured-badge { position: absolute; top: .75rem; right: .75rem; }」,再用 Elements 的父子關係、Computedposition,以及 badge 與 card 的相對角落。 比較前後差異。

Q4除錯驗收 如果完成操作後結果不對,你會先從哪一個證據開始查? 本題線索:index.htmlstyle.css;第一個檢查位置:捲動前後位置、兩張卡片的 Computed z-index、390px/200% 文字畫面與 Tab focus 截圖。 展開解析收合解析

白話解析:

先描述症狀,再提出一個最小假設。本堂常見錯誤是:只增加很大的 z-index,卻沒有重疊元素、底部留白或可聚焦的真實控制項。

對照位置:

對照最後一段 Live Lab:index.htmlstyle.css;檢查方式:先分三件事看:CTA 是否 fixed、內容是否有 padding-bottom、焦點元素是否是 a 或 button。

預期觀察:

你要能指出一個具體位置,而不是一次修改很多檔案。

常見錯誤:

不要先清快取、重裝工具或複製 Solution;先查看第一個可觀察錯誤。

立即驗證:

重新操作並留下「症狀、證據、假設、單一修正、結果」五項紀錄。

常見誤解

本堂任務與驗收

完成推薦徽章、可捲動的 sticky 頁首與 fixed 聯絡入口;重疊層級清楚,窄版與鍵盤焦點不被遮住。

官方延伸閱讀

下載講師版 Markdown:需要授課或離線查閱時使用,內容包含完整教學節奏。