讓網頁更炫砲!CSS Animation

Paul寶羅成長543
CS自學之路
Published in
10 min readSep 10, 2021

關於網頁的設計與排版,為了增加與使用者的互動性,設計師與工程師會利用各種絢麗且具故事性的方式來吸引你我的眼球。其中css 動畫效果也是一種常見的操作。這也滿足了css transition的制式化轉場,創造畫面的多樣性。

動畫的定義:關鍵影格 keyframe

關鍵影格你可以試著當做是拍一部動畫電影當中的劇本或是腳本,而劇本總會有劇名也就是後面要帶入的動畫名稱。然而在網頁的世界裡透過定義關鍵影格(劇本)加上瀏覽器自動運算當中的漸變過程,就成為我們熟知的 CSS 動畫。

//css
div {
width: 100px;
height: 100px;
background-color: red;
animation-name: example;
animation-duration: 4s;
}
@keyframes example {
0% {background-color: red;}
25% {background-color: yellow;}
50% {background-color: blue;}
100% {background-color: green;}
}

上述的程式碼簡單示範animation的初始定義,特別留意@ketframes就是關鍵影格的設定。後面要代入的是一個你為這個動畫取的名字(可自由設定)。

因此我在製作動畫之前,必然會有個定義動畫的起手示@keyframes,語法:

@keyframes 動畫的名稱 {
0% {動畫的一開始是0%}
25% {動畫的中途點}
50% {動畫的一半}
100% {動畫的結束是 100%}
}

若無寫上0%或100%,程式會自動幫我們演算,當然結果是不是如果們所想的就不盡然,最好還是加上開頭結尾。

請注意這裡的數值一定是寫上百分比,相較於過去我們使用的css單位,animation有特別的規定。

相同層級的百分比,屬性若相同則後者會蓋過前者,屬性不同則兩者都會觸發。

除了上述的寫法,css動畫關鍵影格還能使用from/to的寫法,接為等價。from 表示起始,也就是 0% ,to 表示結束,相對 100% 。因為數值範圍是 0%~100%,所以超過這個範圍的都是錯誤的。

@keyframes example {  from {
background-color: red;
}
25% {
background-color: yellow;
}
50% {
background-color: blue;
}
to {
background-color: green;
}
}

CSS動畫八個屬性值:

  • animation-name : 動畫名稱,可自由命名。(劇本、腳本名字)

名稱可以加引號、亦可不加引號:

@keyframes PAUL { … }
@keyframes “PAUL” { … }

名稱大小寫有區別:

@keyframes PAUL { … }
@keyframes paul { … }

特殊字元不能使用,但是用引號框起來就可以:

CSS 動畫有兩個保留字:initial 和 None,因此我們在命名上不能用這兩個字作為動畫的名稱,如果真的要用,只要引號將關鍵字框起來即可。

@keyframes initial { … }    /* 不可使用 */ 
@keyframes None { … } /* 不可使用 */
@keyframes “initial” { … } /* 可以用 */
@keyframes “None” { … } /* 可以用 */
  • animation-duration(動畫播放的時間) :動畫持續時間,或可稱作「播放一次」動畫需要的時間,單位為 秒 ( s ) 或毫秒 ( ms ),預設值 0s,如果沒有設定或將其設為 0s,就不會播放動。
  • animation-delay :動畫延遲開始的時間,代表的是動畫要延後多久才開始播放,單位為 秒 ( s ) 或毫秒 ( ms ),預設值 0s,如果沒有設定或將其設為 0s,動畫就會直接播放不會延遲。

如果將延遲播放時間設定為「負值」,例如 -4s、-6s,得到的結果就「不會延遲,而是快轉」,假設一段動畫要 10 秒,animation-delay 設定為 -1s,那麼動畫將會直接從第9秒的位置開始播放,播放三秒後停止 ( 類似 10–1=9 的概念 )。

  • animation-iteration-count : 動畫播放次數,預設值是1次,如果設定為 infinite 動畫就會無止盡的播放下去。
  • animation-direction :動畫播放方向。

normal:正常播放,從 0% 到 100% ( 預設值 )。

reverse:反轉播放,從 100% 到 0%。

alternate:正反轉輪流播放,奇數次為 0% 到 100%,偶數次為 100% 到 0%,若動畫播放次數只有一次就只會正常播放。

alternate-reverse:alternate 的相反,奇數次為 100% 到 0%,偶數次為 0% 到 100%,若動畫播放次數只有一次就只會反轉播放。

  • animation-timing-function : 動畫的速度,漸變式函式。與transition相同都能使用 Cubic Bezier 調整速率。

linear 均速

photo by.OOXX

ease、ease-in、ease-out、ease-in-out

photo by.OOXX
  • animation-fill-mode : 填充模式,意思是動畫播放前後的狀態。

none:預設值,不論動畫播放次數,結束後一律返回原始狀態

forwards:動畫結束後,保持在最後一個影格狀態。

backwards:動畫結束後,保持在第一個影格狀態 ( 但實際測試和 none 效果一樣 )。

both:依據動畫的次數或播放方向,保持在第一個影格或最後一個影格狀態,相當實用

  • animation-play-state : 動畫播放與暫停的狀態

running:預設值,表示動畫運行。

paused:表示動畫暫停。

以上這8種屬性,可簡寫成:

animation: name| duration | timing-function | delay | iteration-count | direction | fill-mode | play-state;

縮寫除了在程式碼上簡短許多,更可以讓「同一個元素套用多組動畫」,用法只需要在後方用逗點分隔即可。

CSS Keyframes Rule

上述介紹的是在css選擇器當中搭配HTML來操作animation,如果我們想用 JavaScript 操控 CSS 動畫就會用到接下要介紹的CSS Keyframes Rule,一般來說要在JS操作css動畫,都是直接更換動畫名稱,不然就是修改、添加或刪除 class 來實現,然而如果知道 CSSKeyframesRule,就能夠直接修改動畫內容。

修改動畫內容,就需要用到下列幾種方法:

  • findRule():找出對應規則。
  • appendRule():添加規則。
  • deleteRule():刪除規則。

來看看下面這個例子,我們先設計一個單純的動畫,是一個色塊會由畫面左邊出發往右移動,初始為紅色背景色,到50%中繼點時顏色變化為綠色,來到終點轉為藍色之後折返。如果我們想再中繼點做顏色變化,可以搭配上述的語法來呈現,這裡就會操作到JS的DOM,並且額外設計一個按鈕來做事件監聽。

特別關注js的程式碼,keyframes.findRule(‘50%’) 就是找到50%中繼點的規則意思,下一段keyframes.deleteRule(‘50%’)及把這個規則刪除,最後我們要添加新的關鍵影格的規則給它也就是keyframes.appendRule(‘50% {left:100px; background:#000;}’)。

根據MDN的說法:CSS animations 有三種好處:

  1. 對於不複雜的動畫來說,CSS animation 是好選擇。你甚至不必懂得 JavaScript。
  2. 在資源消耗上,CSS animation 有優勢,即使在系統負載超過 50% 仍可有效運作。在 JavaScript 上要達到一樣的目的有賴於你寫出品質非常好的 code。事實上,CSS animation 在運作上可以適時的減少 frame 量或以其它技術減少資源消耗。
  3. CSS animation 讓瀏覽器來負責動畫的產生過程,如此可以擁有較好的優化。

animations 和 transitions 大比拼:

animations 和 transitions 最大的不同在於,tansitions 是當參數改變時觸發,而 animations 則是直接就執行,所以動畫效果需要明確的指定關鍵影格的參數。

CSS3簡寫順序:

Transition

[property 名稱] [duration 時間] [timing-function 特效] [delay 延遲]

Animation

[name 名稱] [duration 時間] [timing-function 特效] [delay 延遲][iteration-count 次數] [direction 方向] [fill-mode 填充模式] [play-state 播放狀態]

簡單差異比較:

Animation:

  1. 可以自行撰寫動畫 開始、進行間、結束時各階段的變化,適合用來做較細微的動畫表現。需要明確的指定關鍵影格(@keyframes)的參數。
  2. 網頁加載時會直接執行,可以自行控制各階段動畫的變化。

Transition:

  1. 需要事件觸發,無法在網頁開始時就啟動。
  2. 一次性的轉場,不能重複發生,除非重複觸發。
  3. 只有開始與結束兩個狀態,沒有中間的關鍵影格。

補充說明:

如果想要「混用 transitionanimation 」是否可行?

事實上可以這麼操作,不過有可能會因為CSS權重關係,達不到預期效果,因此建議單獨使用轉場或動畫。transition 的權重是依照CSS規範等級在排序,但是 animation 卻是超越這一切(甚至是 !important 的權重),獨立而強加的渲染 animation 設定的屬性。

來看個極端的例子:

我們預期的效果:

  1. 當點擊 checkbox 時,box 的 animation 會在3毫秒內搖10下,並且開始與結束會下降10px,。
  2. hover 時,box 的 transition 會在3毫秒下降 30px 並且變紅色。

最終結果:

相同屬性的 top 在動畫播放時間,就算 hover box 還是吃到 animationtop: 10px ,一直到搖完10次,才吃得到 transitiontop: 30px;

不同屬性的 background 不管是不是在動畫播放時間,都會在 hover 時,讓 box 變紅色。

參考資料:

  1. CSS 動畫CSS animation 設定
  2. 完整解析 CSS 動畫 ( CSS Animation )
  3. 前端新手村 Animations (前傳)
  4. Day27:小事之 Transition 與 Animation
  5. 强大的CSS动画:Transition与Animation

--

--

Paul寶羅成長543
CS自學之路

自律是通往自由的道路,不斷探索自我學習與人生修煉的種種課題。