LESSON-13 · 零基礎學生教材
CSS 進階:Transition、動畫與樣式整理
完成一個 390px 不溢出的可操作示範:按鈕與服務卡片在 hover、移出、Tab focus 時有清楚但短暫的變化;animation 與 transition 能分辨;reduced motion 下移除非必要位移與動畫,focus 仍清楚。
先理解:這堂課解決什麼問題?
服務型網站的 HTML 已經能顯示內容,但按鈕和卡片的狀態切換太突然;本堂只處理 CSS 狀態變化、簡短 animation 與使用者的減少動態偏好。
本堂要完成:完成一個 390px 不溢出的可操作示範:按鈕與服務卡片在 hover、移出、Tab focus 時有清楚但短暫的變化;animation 與 transition 能分辨;reduced motion 下移除非必要位移與動畫,focus 仍清楚。
學習邊界:先完成「用 class、狀態與 transition 做出可驗收的按鈕與服務卡片回饋」,不提前引入尚未教過的框架或建置工具。
先備知識與操作環境
本堂先備:服務型網站的 HTML 已經能顯示內容,但按鈕和卡片的狀態切換太突然;本堂只處理 CSS 狀態變化、簡短 animation 與使用者的減少動態偏好。 需要的檔案是 index.html、style.css、main.js、examples/minimal.html、.primary-button、.service-card、@keyframes attention、prefers-reduced-motion。若尚未理解這些位置,先開啟 README 的最小實驗,再開始階段練習。
- 檔案位置:先找到
index.html、style.css、main.js、examples/minimal.html、.primary-button、.service-card、@keyframes attention、prefers-reduced-motion,再從本頁的最小實驗開始。 - 瀏覽器:開啟最小實驗與階段頁;每次修改後儲存並重新整理。
- DevTools:依本堂內容使用 Elements、Styles、Computed、Console 或 Network,記下第一個可觀察證據。
- 操作習慣:每次只修改一個檔案或一個責任,先預測、再操作、最後驗收。
先做最小實驗:先看見結果
這不是期末網站,而是一個可以直接看到本堂核心結果的最小實驗。先完成一次操作,再回到檔案和名詞卡對照。
- 入口:開啟
examples/minimal.html。 - 操作:開啟
examples/minimal.html,先移入和移出卡片與按鈕,再只用 Tab 操作;最後在 DevTools Rendering 切換 prefers-reduced-motion。 - 預期:正常偏好下看到按鈕/卡片的短暫位移與陰影、推薦標籤的短 animation;reduce 下位移與 animation 被移除,Tab focus 仍清楚,390px 沒有水平捲軸。
- 重設:重新整理
examples/minimal.html;切換偏好後重新整理,再回到預設偏好做一次對照。
學生練習流程
依序完成每一張卡;目前只聚焦一個步驟,先操作,再用可觀察證據確認結果。
-
1
最小實驗
先閱讀本頁的問題、檔案地圖、名詞卡與最小例子。 -
2
Step 2
自己回答互動問答 4 題,再展開解析。 -
3
最小實驗 2
開啟最小實驗,實際操作一次並記下證據。 -
4
Starter
把 Starter 複製到自己的工作資料夾,照 3 張微步驟卡逐一完成;每一步都要看到結果再繼續。 -
5
Checkpoint
前往 Checkpoint,只處理 1 個本堂核心缺口;先預測,再用指定證據驗收。 -
6
Solution
前往 Solution,先看逐檔差異與修改原因,再決定要不要把完整內容帶回自己的檔案。 -
7
變體驗收
完成情境變體與獨立挑戰,留下檔案位置、操作、結果與驗收證據,並閱讀下一堂銜接:下一堂會用 JavaScript 函式,在穩定的HTML/CSS上加入可測試的行為。
檔案地圖:每個位置負責什麼?
先不要急著背檔名;請把檔案位置和責任連起來。你在階段頁會看到同一份檔案的可執行版本。
index.html首頁入口:呈現商家第一印象與主要 CTA。style.cssCSS 樣式檔:放置本堂「用 class、狀態與 transition 做出可驗收的按鈕與服務卡片回饋」相關的版面規則。main.jsJavaScript 腳本:放置本堂「用 class、狀態與 transition 做出可驗收的按鈕與服務卡片回饋」相關的互動邏輯。examples/minimal.htmlHTML 頁面:承載本堂「用 class、狀態與 transition 做出可驗收的按鈕與服務卡片回饋」所需的內容與入口。.primary-button主要按鈕 class:標示訪客最重要的行動入口。.service-card服務卡片 class:控制每張服務資訊卡的共用樣式。@keyframes attention定位或條件語法:用來指定本堂要觀察的元素、狀態或 viewport(@keyframes attention)。prefers-reduced-motion動態偏好條件:尊重使用者減少動畫的系統設定。
先學會這些詞
先從名詞、英文與白話意思開始;每次只展開一張名詞卡,再對照正式定義、範例與驗收證據。專業術語、語法、檔案路徑會使用不同樣式。第一次遇到術語時,先回到這裡,不要靠猜。
選擇器與狀態
5 個詞classclass attribute 白話意思:給一個或多個 HTML 元素貼上的可重用名稱。 展開查看正式定義、範例與驗收證據
- 正式定義
- HTML 元素上的 class attribute 會成為 CSS selector 的匹配依據;同一個 class 可以被多個元素共用。
- 什麼時候用
- 要讓按鈕與服務卡片各自套用一組可重用樣式時。
- 最小範例
- <button class="primary-button">查看方案</button>。
- 可觀察證據
- Elements 能看到 class 名稱;Styles 能顯示
.primary-button是否命中。 - 容易混淆
- 和 id 混淆;class 可以共用,id 通常只識別一個元素。
selectorCSS selector 白話意思:告訴 CSS 要把規則套用到誰。 展開查看正式定義、範例與驗收證據
- 正式定義
- CSS 規則中用來匹配文件元素的模式;本堂先使用 class selector 與 pseudo-class selector。
- 什麼時候用
- 要讓
.primary-button或.service-card套用規則時。 - 最小範例
- .service-card { padding: 1rem; } 會選取所有 service-card 元素。
- 可觀察證據
- Elements 的 Styles 顯示規則命中;沒有命中時會看不到預期宣告。
- 容易混淆
- 和 property 混淆;selector 決定對誰作用,property 決定改什麼。
狀態state 白話意思:同一個元素在不同情況下的樣子,例如平常、滑入或取得焦點。 展開查看正式定義、範例與驗收證據
- 正式定義
- 由使用者互動或文件條件造成、可被 CSS selector 表達的元素呈現狀態。
- 什麼時候用
- 要比較按鈕尚未操作、滑鼠移入、移出與鍵盤 focus 時。
- 最小範例
- 同一顆按鈕可以有一般狀態與 .primary-button:hover 狀態。
- 可觀察證據
- 先在畫面操作,再在 Styles 看到目前匹配的規則。
- 容易混淆
- 和元素本身混淆;元素沒有換掉,只是目前狀態改變。
:hoverhover pseudo-class 白話意思:滑鼠游標移到元素上時的狀態。 展開查看正式定義、範例與驗收證據
- 正式定義
- CSS pseudo-class,用來匹配使用者指標目前懸停的元素。
- 什麼時候用
- 要提供滑鼠移入時的顏色、陰影或輕微位移時。
- 最小範例
- .primary-button:hover { transform: translateY(-2px); }。
- 可觀察證據
- 滑鼠移入與移出按鈕時,畫面在兩個狀態間變化。
- 容易混淆
- 和
:focus-visible混淆;hover 依賴指標,鍵盤使用者不一定會觸發它。
:focus-visiblefocus-visible pseudo-class 白話意思:鍵盤 Tab 走到元素時,顯示目前操作位置的狀態。 展開查看正式定義、範例與驗收證據
- 正式定義
- CSS pseudo-class,用來匹配瀏覽器判斷應顯示可見鍵盤焦點指示的元素。
- 什麼時候用
- 按鈕、連結或表單需要讓鍵盤使用者知道目前位置時。
- 最小範例
- .primary-button:focus-visible { outline: 3px solid #f3b63f; }。
- 可觀察證據
- 不用滑鼠,按 Tab 走到按鈕時仍看得到清楚的 outline。
- 容易混淆
- 和
:hover混淆;focus-visible 是鍵盤操作的驗收入口,不是滑鼠裝飾。
轉場設定
5 個詞transitionCSS transition 白話意思:讓狀態改變在一小段時間內平順地從 A 走到 B。 展開查看正式定義、範例與驗收證據
- 正式定義
- 當可動畫的 CSS property 值因狀態改變而不同時,瀏覽器在兩個值之間計算中間畫面的效果。
- 什麼時候用
- 按鈕 hover、focus 或卡片 focus-within 需要短暫視覺回饋時。
- 最小範例
- transition: transform 200ms ease; 要寫在一般 selector,而不是只寫在 hover。
- 可觀察證據
- Computed 能看到 transition;移入與移出都能觀察到變化。
- 容易混淆
- 和 animation 混淆;transition 需要狀態前後值,animation 可依 keyframes 自己播放。
transition-propertytransition-property 白話意思:指定哪些 CSS property 要平順改變。 展開查看正式定義、範例與驗收證據
- 正式定義
- transition shorthand 中描述要套用過渡效果的 property 清單。
- 什麼時候用
- 只想讓 transform、background-color 或 box-shadow 改變,而不想讓所有屬性都動時。
- 最小範例
- transition-property: transform, box-shadow;。
- 可觀察證據
- Computed 或 Styles 顯示實際 transition 的 property,而不是
all。 - 容易混淆
- 和 property 一般概念混淆;它是 transition 要追蹤的 property,不是要被選取的 selector。
durationtransition-duration 白話意思:指定過渡要花多久時間。 展開查看正式定義、範例與驗收證據
- 正式定義
- transition-duration 設定 CSS property 從起點到終點完成變化所需的時間。
- 什麼時候用
- 要讓互動短暫、可感覺但不拖慢操作時。
- 最小範例
- transition-duration: 200ms;。
- 可觀察證據
- Computed 能看到 200ms;移動滑鼠離開時不會延遲很久。
- 容易混淆
- 和 delay 混淆;duration 是變化本身多久,delay 是多久後才開始。
timing functiontransition-timing-function 白話意思:決定變化速度是平均、先快後慢,或其他節奏。 展開查看正式定義、範例與驗收證據
- 正式定義
- transition-timing-function 定義時間進度如何映射到 property 值進度的函式。
- 什麼時候用
- 要讓短動畫的速度感自然,而且能在 Computed 讀出使用的節奏時。
- 最小範例
- transition-timing-function: ease;。
- 可觀察證據
- Computed 顯示
ease,且 200ms 內的變化不是突然跳到終點。 - 容易混淆
- 和 duration 混淆;timing
function改變速度曲線,duration 改變總時間。
delaytransition-delay 白話意思:指定過渡開始前要等多久。 展開查看正式定義、範例與驗收證據
- 正式定義
- transition-delay 設定 property 值變更後,瀏覽器等待多久才開始過渡。
- 什麼時候用
- 只有在確實需要錯開時才使用;本堂示範讀懂它,不把互動故意拖慢。
- 最小範例
- transition-delay: 0ms; 表示不額外等待。
- 可觀察證據
- Computed 能看到 delay;按 Tab 後 focus outline 不會被不必要地延遲。
- 容易混淆
- 和 duration 混淆;delay 在開始前等待,duration 是開始後持續多久。
動態效果與減少動效
3 個詞transformCSS transform 白話意思:改變元素的幾何呈現,例如上下移動,但不直接改文件流位置。 展開查看正式定義、範例與驗收證據
- 正式定義
- 以矩陣或函式對元素進行平移、旋轉、縮放等視覺幾何轉換的 CSS property。
- 什麼時候用
- 要做小幅度、非必要的 hover 或 focus 回饋時。
- 最小範例
- transform: translateY(-2px);。
- 可觀察證據
- 畫面看到卡片或按鈕微微上移;reduced motion 時這個位移被移除。
- 容易混淆
- 和改變文件排列的版面規則混淆;transform 是視覺轉換,本堂只用它做小幅度回饋。
animation/@keyframesCSS animation and keyframes 白話意思:讓元素依一組時間點自行播放一段動畫。 展開查看正式定義、範例與驗收證據
- 正式定義
- animation 使用 @keyframes 定義的起點、終點或中間影格,依時間與播放設定改變 property。
- 什麼時候用
- 要和需要狀態前後值的 transition 做小型比較時。
- 最小範例
- @keyframes attention { from { opacity: .4; } to { opacity: 1; } }。
- 可觀察證據
- Styles 能看到 animation,推薦標籤只在載入時播放一次;reduced motion 時不播放。
- 容易混淆
- 和 transition 混淆;animation 不需要 hover 才能依 keyframes 播放。
prefers-reduced-motionprefers-reduced-motion media feature 白話意思:讀取使用者希望減少畫面動態的系統偏好。 展開查看正式定義、範例與驗收證據
- 正式定義
- CSS media feature,讓作者依使用者代理程式提供的減少動態偏好,移除、縮短或替換非必要 motion。
- 什麼時候用
- 頁面有 transform、transition 或 animation,又要讓使用者選擇較穩定的畫面時。
- 最小範例
- @media (prefers-reduced-motion: reduce) { .service-card__tag { animation: none; } }。
- 可觀察證據
- Rendering 切換 reduce 後 animation 不播放、位移被移除,Tab focus outline 仍存在。
- 容易混淆
- 和完全禁止所有視覺變化混淆;顏色或 focus 仍可保留,只處理非必要動態。
最小例子:先看懂,再複製
這段只保留本堂第一個微成果。先預測結果,再逐行讀;完整檔案請開啟下方最小實驗。
<button id="action" class="primary-button" type="button">查看推薦方案</button>Live Lab:逐段讀碼與驗證
每一步只回答五件事:為什麼做、改哪裡、會看到什麼、用什麼證據確認、卡住先查什麼。
-
Step 1
先把 HTML class 對到 CSS selector
- 目的
- 先建立元素、class 與 selector 的最小對應,避免把 CSS 貼到不存在的元素上。
- 修改位置
index.html的 #action 與.service-card
只替 #action 加上 class="primary-button",保留 id、type 與按鈕文字。- 預期結果
- Elements 中按鈕的 class 變成 primary-button;畫面結構不變,現在可以開始讓 CSS 精準命中它。
- 驗收證據
- Elements 搜尋 .primary-button 與
.service-card,確認按鈕為 1 個、服務卡片為 2 個。 - 卡住先查
- 只在 Elements 點擊按鈕,逐字比對 class 是否為 primary-button。
-
Step 2
先在一般 selector 建立 transition
- 目的
- 先只處理狀態前後值的平順變化,不把 transition 寫進 hover 或 focus 狀態。
- 修改位置
style.css的 .primary-button 與.service-card
在一般 selector 寫入指定 property、duration 與 timingfunction;hover、focus-visible、focus-within 只寫狀態改變後的值。- 預期結果
- 滑鼠移入與移出按鈕、按 Tab 到按鈕、移入卡片時,變化都短暫且可辨識;此步先不期待 keyframes animation。
- 驗收證據
- Styles 命中一般 .primary-button 與
.service-card;Computed 可讀到 transition-property、duration、timing-function;Tab focus 仍有 outline。 - 卡住先查
- 只在 Styles 搜尋 .primary-button 的一般規則,確認 transition 是否位於狀態規則之外。
-
Step 3
拆解 transition 的四個組成
- 目的
- 把 property、duration、timing
function與 delay 分開讀,避免只背一整串 shorthand。 - 修改位置
style.css的 .primary-button transition 宣告
逐一指出 transition-property、transition-duration、transition-timing-function 與 transition-delay 在 shorthand 中的責任。- 預期結果
- 學生能指出三個 property、總時間、速度曲線與等待時間,並在 Computed 讀到目前值。
- 驗收證據
- Computed 看到 transform/background-color/box-shadow、200ms、ease 與 0s;不需要把 Console 當成 CSS 證據。
- 卡住先查
- 只看 .primary-button 的 transition 那一行,先圈出 property、時間、速度與等待四個部分。
-
Step 4
用 @keyframes 比較 animation
- 目的
- 讓學生看見 animation 可以依 keyframes 自己播放,不需要 hover 才有前後狀態。
- 修改位置
style.css的 @keyframes attention 與.service-card__tag
建立 attention 的 from/to 影格,並只讓推薦標籤播放一次短動畫。- 預期結果
- 重新整理時推薦標籤播放一次短 animation;hover/focus 的按鈕與卡片仍由 transition 負責。
- 驗收證據
- Styles 看到 @keyframes 與 animation;重新整理後觀察標籤,並比較按鈕 transition 的 Computed。
- 卡住先查
- 只搜尋 @keyframes attention,確認影格名稱和 animation 宣告使用同一個名稱。
-
Step 5
用 reduced motion 提供替代呈現
- 目的
- 理解 reduced motion 不是把所有樣式刪光,而是移除、縮短或替換非必要動態。
- 修改位置
style.css的@media(prefers-reduced-motion: reduce)
在 reduce 條件中縮短按鈕背景色 transition、移除卡片 transition、停止 keyframes,並取消 hover/focus 的位移;保留 focus-visible outline。- 預期結果
- 正常與 reduce 的差異可被看見:reduce 不再有非必要位移或載入 animation,但按 Tab 仍看得到清楚 focus ring。
- 驗收證據
- DevTools Rendering 切換 prefers-reduced-motion;比較正常/reduce 的 Computed、畫面位移與 Tab focus。
- 卡住先查
- 只先確認 Rendering 的 reduce 設定是否真的開啟,再重新整理一次。
-
Step 6
修正 transition 寫錯位置的真實缺口
- 目的
- 從可重現的移入/移出差異,理解 transition 必須放在共同存在的狀態基底。
- 修改位置
checkpoint/files/style.css的 .primary-button:hover
把 transition 移到 .primary-button 一般 selector,讓 hover/focus-visible 只留下 transform、background-color 與 box-shadow 的終點值。- 預期結果
- 滑入和移出都平順;Computed 在一般按鈕狀態也能看到 transition 設定。
- 驗收證據
- 記錄修正前移入/移出、Styles 的宣告位置與修正後 Computed 的 property/duration/timing-function。
- 卡住先查
- 只查看 .primary-button
:hover區塊,確認裡面沒有 transition 宣告。
讀碼順序:先找入口,再用畫面、Elements、Styles、Computed、Tab 與 Rendering 驗證;本堂不需要用 Console 或 Network 假裝證明 CSS 是否有效。
互動問答
先回答目前這一題,再展開解析;完成後按下一題,讓每一次回答都回到檔案或瀏覽器完成驗證。
Q1概念理解
「class(class attribute)」在本堂要解決什麼問題?
本題線索:class;回到名詞卡與 Elements 能看到 class 名稱;Styles 能顯示 .primary-button 是否命中。
展開解析收合解析
白話解析:
給一個或多個 HTML 元素貼上的可重用名稱。 正式來說,HTML 元素上的 class attribute 會成為 CSS selector 的匹配依據;同一個 class 可以被多個元素共用。
對照位置:
回到名詞卡「class」,再看 Elements 能看到 class 名稱;Styles 能顯示 .primary-button 是否命中。
預期觀察:
你應該能用自己的話說出:要讓按鈕與服務卡片各自套用一組可重用樣式時。
常見錯誤:
不要只回答「它是class」;那是重複名詞,不是說明責任。
立即驗證:
開啟 examples/minimal.html,依序做「開啟 examples/minimal.html,先移入和移出卡片與按鈕,再只用 Tab 操作;最後在 DevTools Rendering 切換 prefers-reduced-motion。」並記下畫面或工具證據。
Q2程式碼閱讀
修改指定規則後,你預測畫面會看到什麼?
本題線索:index.html 的 #action 與 .service-card;要修改:只替 #action 加上 class="primary-button",保留 id、type 與按鈕文字。;觀察:Elements 搜尋 .primary-button 與 .service-card,確認按鈕為 1 個、服務卡片為 2 個。
展開解析收合解析
白話解析:
先看檔案責任,再預測結果。這一步的目的:先建立元素、class 與 selector 的最小對應,避免把 CSS 貼到不存在的元素上。
對照位置:
對照 Live Lab Step 1,位置是 index.html 的 #action 與 .service-card;範例內容:<button id="action" class="primary-button" type="button">查看推薦方案</button>
預期觀察:
Elements 中按鈕的 class 變成 primary-button;畫面結構不變,現在可以開始讓 CSS 精準命中它。
常見錯誤:
如果只改了檔案但沒有結果,先不要重寫全部;只在 Elements 點擊按鈕,逐字比對 class 是否為 primary-button。
立即驗證:
實際操作後檢查 Elements 搜尋 .primary-button 與 .service-card,確認按鈕為 1 個、服務卡片為 2 個。。
Q3概念比較
「class」和「selector」在本堂的責任有什麼不同?
本題線索:比較 class 與 selector;操作位置:style.css 的 .primary-button 與 .service-card
展開解析收合解析
白話解析:
class:給一個或多個 HTML 元素貼上的可重用名稱。;selector:告訴 CSS 要把規則套用到誰。
對照位置:
對照兩張名詞卡的正式定義:HTML 元素上的 class attribute 會成為 CSS selector 的匹配依據;同一個 class 可以被多個元素共用。/CSS 規則中用來匹配文件元素的模式;本堂先使用 class selector 與 pseudo-class selector。
預期觀察:
你應該能指出兩者分別出現在哪個檔案或工具,以及哪一個結果會改變。
常見錯誤:
不要把「改變畫面」當成所有技術的責任;先說清楚誰負責結構、呈現、行為或驗收。
立即驗證:
在 style.css 的 .primary-button 與 .service-card 做「在一般 selector 寫入指定 property、duration 與 timing function;hover、focus-visible、focus-within 只寫狀態改變後的值。」,再用 Styles 命中一般 .primary-button 與 .service-card;Computed 可讀到 transition-property、duration、timing-function;Tab focus 仍有 outline。 比較前後差異。
Q4除錯驗收
如果完成操作後結果不對,你會先從哪一個證據開始查?
本題線索:checkpoint/files/style.css 的 .primary-button:hover;第一個檢查位置:記錄修正前移入/移出、Styles 的宣告位置與修正後 Computed 的 property/duration/timing-function。
展開解析收合解析
白話解析:
先描述症狀,再提出一個最小假設。本堂常見錯誤是:只把 200ms 改成 100ms,或只補 hover 的 transform,沒有移動 transition 的宣告位置。
對照位置:
對照最後一段 Live Lab:checkpoint/files/style.css 的 .primary-button:hover;檢查方式:只查看 .primary-button:hover 區塊,確認裡面沒有 transition 宣告。
預期觀察:
你要能指出一個具體位置,而不是一次修改很多檔案。
常見錯誤:
不要先清快取、重裝工具或複製 Solution;先查看第一個可觀察錯誤。
立即驗證:
重新操作並留下「症狀、證據、假設、單一修正、結果」五項紀錄。
常見誤解
- 看到畫面沒有變化,不代表程式沒執行;先確認檔案、路徑、元素與狀態證據。
- 能複製 Solution 不代表理解;請先說出修改哪個檔案、預期哪個結果、用什麼證據確認。
- 本堂只使用既定的 HTML、CSS、JavaScript、Vue CDN、Apps Script mock 與 Cloudflare Pages 驗收範圍。
本堂任務與驗收
完成一個 390px 不溢出的可操作示範:按鈕與服務卡片在 hover、移出、Tab focus 時有清楚但短暫的變化;animation 與 transition 能分辨;reduced motion 下移除非必要位移與動畫,focus 仍清楚。
- 能用 HTML class 與 CSS selector 對應 留下可重現證據。
- 能用 hover 進出 留下可重現證據。
- 能用 Tab focus 留下可重現證據。
- 能用 Computed 的 transition-property/duration/timing-function 留下可重現證據。
- 能用 正常與 reduced motion 對照 留下可重現證據。
- 能用 390px 無水平捲軸 留下可重現證據。
- Starter、Checkpoint、Solution 的入口都能開啟並知道三者差異。
- 遇到問題時能先寫出症狀,再檢查一個最小假設。
官方延伸閱讀
下載講師版 Markdown:需要授課或離線查閱時使用,內容包含完整教學節奏。