National Central University
Uedu Main Site
Explore Uedu
Student Console
Register as Member/Login
Research Informed Consent Center
Survey Center
Educational Big Data Challenge
Claim or create a course
Try an AI Scenario Task
Support & Messages
Uptime Data

UeduGPTs

--

Jupyters

3

Local AI

--

Uedu Code

--

中央大學 AQI 80 24°C PM2.5 21
AI Reply Desktop Notifications

Show a desktop notification when the AI TA finishes replying

Chat Message Notifications

Notify me when classmates post messages in the forum

Sound notification

Play an alert sound whenever there is a new notification

Unit 22

轉場、動畫與 CSS 變數

transition、transform、@keyframes、CSS 變數與深色模式
Interaction 25 minute(s)

Learning Objectives

  • 用 transition 設定要變化的屬性、時間、速度曲線與延遲,讓樣式改變時平順過渡
  • 用 transform 的 translate、scale、rotate 移動、縮放、旋轉元素,而不影響其他元素的位置
  • 用 @keyframes 與 animation 寫出會自己播放的動畫,並說明為什麼優先對 transform 與 opacity 做動畫
  • 用 prefers-reduced-motion 尊重使用者「減少動態」的系統設定
  • 用 CSS 自訂屬性(變數)與 var() 管理顏色,並用 prefers-color-scheme 做出深色模式

動態是用來說明變化的

滑鼠移到按鈕上,顏色「啪」一聲換掉,和在 0.2 秒內慢慢變深,給人的感覺不一樣: 後者讓你看得出「這個東西有反應,而且是從原來的樣子變過來的」。 選單滑出來、卡片展開、資料載入中的小點點,都是用動態告訴使用者畫面上發生了什麼變化。

這一課學三件事:

工具 用途 什麼時候播放
transition(轉場) 屬性值改變時,在一段時間內慢慢過渡 樣式改變時(例如 :hover、加上 class)
@keyframes + animation(動畫) 自己定義好幾個關鍵畫面,照順序播放 一載入就播,可以重複
自訂屬性(變數) 把顏色等數值取個名字,集中管理 不是動態,但讓「整頁換色」變得容易

動態用得好,畫面比較好懂;用太多會讓人分心,對有前庭疾患的人甚至會造成頭暈不適。 所以這一課也會教你怎麼尊重使用者「減少動態」的設定。

transition:讓變化有過程

transition 寫在元素平常的樣式上,說明「哪個屬性改變時,要花多久過渡」:

.join {
  background-color: #3C6F9A;
  transition: background-color 0.2s ease-out 0s;
  /*          要過渡的屬性   時間  速度曲線  延遲 */
}
.join:hover {
  background-color: #1f4a6e;   /* 滑鼠移上來時,顏色在 0.2 秒內慢慢變深 */
}
部分 對應的單一屬性 說明
屬性 transition-property 例如 background-color、transform;all 表示全部(方便但容易讓不想動的東西也動)
時間 transition-duration 0.2s 或 200ms;介面上的小變化通常在零點幾秒內
速度曲線 transition-timing-function 過程中的快慢分配,見下一段
延遲 transition-delay 等多久才開始

把 transition 寫在 .join 而不是 .join:hover 上,滑鼠移開時顏色才會同樣慢慢變回去。 要讓兩個屬性各有不同的時間,用逗號分開:transition: background-color 0.2s, transform 0.3s;。

速度曲線(timing function)決定「同樣花 0.3 秒,哪一段快、哪一段慢」:

值 過程
linear 從頭到尾等速
ease(預設) 開始稍快、結尾慢下來
ease-in 慢慢起步、越來越快
ease-out 一開始快、最後慢慢停下
ease-in-out 慢慢起步、中間快、慢慢停下
cubic-bezier(x1, y1, x2, y2) 用兩個控制點自訂曲線;y 超過 1 會「衝過頭再彈回」

下面的工具讓你同時比較幾種曲線。

互動工具:時間、速度曲線與延遲

方塊是真的用 transition 移動的;曲線上的圓點是播放時從方塊實際讀回來的位置。曲線越陡的地方,方塊跑得越快。依任務操作。

transform:移動、縮放、旋轉

transform 改變元素畫出來的樣子,但不改變它在版面裡佔的位置,所以旁邊的元素不會被推開:

寫法 效果
transform: translateX(6px) 往右移 6px(translateY 上下、translate(x, y) 兩個方向)
transform: scale(1.1) 放大到 1.1 倍(scale(0.95) 縮小,常用在按下按鈕的回饋)
transform: rotate(90deg) 順時針轉 90 度(展開選單時的箭頭)
transform: translateY(-2px) scale(1.05) 用空白連寫好幾個,依序套用

transform 對 display: inline 的元素(例如一般的 span)沒有效果,要先改成 inline-block 或 block。

為什麼動畫優先用 transform 和 opacity? 瀏覽器把畫面畫出來大致分成幾個階段:算樣式、排版(layout,決定每個元素的位置與大小)、繪製(paint)、合成(composite)。 改 width、top、margin 會讓瀏覽器每一格畫面都重新排版,元素一多就容易卡頓; transform 和 opacity 通常只需要在最後的合成階段處理,不必重新排版,播放起來比較順。

想做的效果 建議寫法 避免的寫法
往右移動 transform: translateX(…) 改 left 或 margin-left
放大 transform: scale(…) 改 width、height
淡入淡出 opacity 改 display(display 不會過渡)

互動練習:按鈕與箭頭的轉場

把滑鼠移到預覽裡的按鈕與連結上:顏色和箭頭都是瞬間跳過去的。加上 transition,按「執行」後再移上去比較。最後替開啟「減少動態」的使用者把轉場關掉。

@keyframes 與 animation

transition 要等樣式改變才播放;動畫可以一載入就自己播,還能重複。分兩步:

1. 用 @keyframes 定義關鍵畫面(取一個名字):

@keyframes pulse {
  from { opacity: 0.3; transform: scale(0.8); }   /* 也可以寫 0% */
  to   { opacity: 1;   transform: scale(1); }     /* 也可以寫 100% */
}

中間還可以加 50% { … } 這類百分比的畫面。

2. 用 animation 套用到元素上:

.dot {
  animation: pulse 0.8s ease-in-out infinite alternate;
  /*         名字  時間  速度曲線     重複次數  方向 */
}
.dot:nth-child(2) { animation-delay: 0.2s; }   /* 第二個點晚一點開始 */
單一屬性 常用值
animation-name @keyframes 的名字
animation-duration 播一次要多久
animation-iteration-count 3、infinite(一直重複)
animation-direction alternate:去程播完播回程,來回擺動
animation-delay 延遲開始
animation-fill-mode forwards:播完停在最後一格

尊重「減少動態」的設定:Windows、macOS、iOS、Android 都有「減少動態」或「移除動畫」的系統設定, CSS 用媒體查詢 prefers-reduced-motion 讀得到。動畫只是裝飾、不是內容時,在這個設定下把它關掉或換成淡入淡出:

@media (prefers-reduced-motion: reduce) {
  .dot { animation: none; }
}

「載入中」這類狀態,動畫關掉之後仍然要有文字說明(例如旁邊的「資料載入中」),資訊才不會跟著消失。

互動練習:載入中的三個點

三個圓點現在是靜止的。寫一段 @keyframes,讓它們依序閃動;動畫只改 opacity 與 transform。最後替開啟「減少動態」的使用者停掉動畫(文字「資料載入中」還在,資訊不會消失)。

小測驗:轉場與動畫

1.

下面的寫法,滑鼠移開按鈕時會怎樣?

.btn { background-color: #3C6F9A; }
.btn:hover { background-color: #1f4a6e; transition: background-color 0.3s; }
2.

想讓卡片從畫面左邊滑進來,下面哪一種寫法播放起來通常最順?

3.

animation: pulse 1s infinite alternate; 裡的 alternate 是什麼意思?

4.

使用者在系統設定開啟了「減少動態」,網頁要怎麼知道?

第 1 次作答

CSS 變數與深色模式

同一個品牌藍出現在標題、按鈕、標籤、邊框,想換顏色就要改十幾個地方。 CSS 自訂屬性(custom property,常叫 CSS 變數)讓你把值取個名字,集中寫在一個地方:

:root {                     /* :root 就是 html 元素,變數會繼承給整頁 */
  --accent: #3C6F9A;        /* 名字一定以兩個連字號 -- 開頭 */
  --bg: #ffffff;
  --text: #1f2933;
}

.tag {
  background-color: var(--accent);       /* 用 var() 取出來 */
  color: var(--bg);
}

.note {
  border-color: var(--line, #cbd2d9);    /* 第二個值是找不到 --line 時的備用值 */
}

變數和一般屬性一樣會繼承,也遵守層疊規則:在某個元素上重新定義,它和它的子元素就用新的值。

深色模式:系統設成深色時,媒體查詢 prefers-color-scheme: dark 會成立。 既然所有顏色都透過變數取用,只要在媒體查詢裡重新定義變數,整頁就跟著換色,其他規則一行都不用改:

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #1e293b;
    --text: #e2e8f0;
    --accent: #8ec5ff;   /* 深色背景上,藍色要調亮,對比才夠 */
  }
}

深色模式不是把顏色全部反過來:純黑底配純白字很刺眼,通常用深藍灰底配淺灰字; 原本的強調色在深色背景上常常不夠亮,要另外挑一個(第 24 課會教你算對比值)。

互動練習:用變數做深色模式

這張課程筆記的顏色寫死在四個地方。改成用變數,再加上深色模式。預覽會跟著你電腦的系統設定:系統是淺色就看到淺色版;把系統切成深色,再按「執行」就會看到深色版。

小測驗:CSS 變數

1.

下面的 .tag 背景是什麼顏色?

:root { --accent: blue; }
.card { --accent: green; }
.tag { background-color: var(--accent); }
<div class="card"><span class="tag">標籤</span></div>
2.

color: var(--brand, #333); 的 #333 是做什麼用的?

3.

所有顏色都已經用變數寫好了。要加上深色模式,最少要改什麼?

第 1 次作答

重點整理

  • transition: 屬性 時間 速度曲線 延遲; 寫在元素平常的樣式上,進出兩個方向都會過渡。
  • 速度曲線決定快慢分配:linear 等速、ease-out 先快後慢、cubic-bezier() 自訂;y 超過 1 會衝過頭。
  • transform 的 translate、scale、rotate 只改畫出來的樣子,不推開旁邊的元素;inline 元素要先改成 inline-block。
  • @keyframes 定義關鍵畫面,animation 套用;infinite 一直重複、alternate 來回播。
  • 動畫優先只改 transform 與 opacity,通常不必每一格重新排版,播放比較順。
  • @media (prefers-reduced-motion: reduce) 裡把裝飾性的動畫關掉,資訊要用文字留下來。
  • CSS 變數:--名字: 值; 定義、var(--名字, 備用值) 取用;會繼承。深色模式只要在 prefers-color-scheme: dark 裡重新定義變數。

下一課介紹 Bootstrap:一套把格線、按鈕、表單這些常用樣式先寫好的 CSS 框架,以及它和你學過的 Flexbox、媒體查詢是什麼關係。

這一課完成了!
Next lesson:Bootstrap
你目前沒有登入,學習進度只存在這個瀏覽器。 Login 後,進度會跟著帳號,換電腦也看得到。