CSS - 動畫

動畫 - Animation

「轉場」與「動畫」可說是兄弟,兩人分工負責了 CSS 世界的動態效果。轉場可以在觸發狀態時,讓起始、結束狀態兩組樣式產生一組簡單的補間動畫,它是容易且強大的效果,但若要製作較為複雜的效果時,這就不是轉場的工作囉,因為它屬於一次性的動畫,例如黑色與白色的補間動畫。若是要黑色變成黃色,再變成白色,再變其他顏色,這時候就是動畫(animation)登場的時候。

其概念與早期動畫軟體 Flash 影格(keyframes)一樣(為 Flash 默哀,1996 年 4 月 10 日 - 2020 年 12 月 31),也就是可以設定好幾個關鍵影格的概念,來告訴瀏覽器在目前關鍵影格到下一個關鍵影格之間要渲染的樣式效果,因此,每個關鍵影格與關鍵影格之間都將會是一組補間動畫,可以形成好幾組補間動畫,產生強大複雜且可循環的動畫效果。

動畫設定

動畫設定以 @keyframes 宣告一組動畫的開始,它必須要一個動畫名稱,{} 大括號區塊裡面描述著動畫的循環行為,可以用百分比來告訴動畫時間分配的進度,也可以用 from 或 to 關鍵字。但請記住一件事,@keyframes 只掌管動畫時間的進度分配及紀錄 CSS 屬性,至於持續時間?重複幾次?延遲時間?速率如何?動畫播放方向?動畫終止時的狀態?動畫是否暫停?等等都由動畫其它屬性來設定,動畫很多屬性,對吧,這就是它比轉場可以設定更複雜的效果原因。以下為一個簡單的動畫範例,當滑鼠移到 .box 元素上時,在 5 秒內,紅>綠>藍>綠>紅 順序變化顏色,並且可以無限循環。

.box {
width: 200px;
height: 200px;
background-color: red;
}
.box:hover {
animation: animate 5s infinite;
}

@keyframes animate {
0% {
background: red;
}

25% {
background: green;
}

50% {
background: blue;
}

75% {
background: green;
}

100% {
background: red;
}
}

動畫屬性

屬性 說明
animation-name 動畫名稱
animation-duration 動畫持續時間,預設 0,單位 s 或 ms。
animation-delay 動畫延遲播放時間,預設 0,單位 s 或 ms。
animation-iteration-count 動畫播放次數,預設 1。其他還有 infinite。
animation-timing-function 動畫加速度函式,預設 ease。其他還有:linear、ease-in、ease-out、ease-in-out
animation-direction 動畫播放方向,預設 normal。其他還有 reverse、alternate、alternate-reverse。
animation-fill-mode 動畫播放前後模式,預設 none。其他還有 forwards、backwards、both。
animation-play-state 動畫播放或暫停狀態,預設 running。其他還有 paused。
div {
width: 100px;
height: 100px;
background: red;

/* 動畫名稱 */
animation-name: animate;
/* 動畫間隔 */
animation-duration: 1s;
/* 速度函式 */
animation-timing-function: ease;
/* 動畫延遲 */
animation-delay: 0.1s;
/* 播放次數 */
animation-iteration-count: infinite;

/* 循環交替或反向播放 */
/* normal(默認,正常播放)、revers(反向播放) */
/* alternate(輪流交替播放,動畫在奇數次 1,3,5 正向播放,在偶數次 2,4,6 反向播放) */
/* alternate-reverse(動畫在奇數次 1,3,5 反向播放,在偶數次 2,4,6 正向播放) */
animation-direction: alternate;
/* forwards(保留動畫結束後的樣式,例如顏色、位置) */
/* backwards(返回動畫一開始的樣式,例如顏色、位置) */
animation-fill-mode: forwards;

/* 縮寫 */
/* animation: name duration timing-function delay iteration-count direction fill-mode play-state; */
animation: animate 1s infinite alternate;
}

/* 宣告關鍵影格為動畫、動畫名稱、開始、結束 */
@keyframes animate {
from {
background: red;
}

to {
background: yellow;
}
}

動畫速率

「動畫速率」與「轉場速率」是一樣的設定,請參考轉場

動畫延遲

「動畫延遲」與「轉場延遲」是一樣的設定,可以注意的是當延遲時間為負值時,例如 -1s、-2s,得到的結果就「不會延遲,而是快轉」,假設一段動畫 animation-duration 要 5 秒,animation-delay 設定為 -2s,那麼動畫將會直接從第 2 秒的位置開始播放,播放 3 秒後停止 ( 5-2=3 的概念 )。

動畫權重

關鍵影格中的 CSS 屬性在「動畫執行期間」會擁有最大絕對的優先權,但是一旦脫離了動畫執行期間,就會恢復到下一階的優先權。
正在執行元素的動畫(@keyframes),權重會提高至行內樣式權重(比 ID 權重高),此外,不要在動畫宣告區塊的屬性後方加上 !important,沒有這種用法,會被忽略。

多組動畫

與轉場一樣可以套用多組效果。

/* 可以套用一個以上的動畫到同個元素,屬性值需對應,fadeIn 1s、blink 3s */
.fade {
animation-name: fadeIn, blink;
animation-duration: 1s, 3s;
}

省略 from 與 to

沒有指定 0% 或 from 的 keyframe,瀏覽器會以要附加動畫的屬性原始值,建構一個 0% 的 keyframe,同樣的,沒有定義 100% 或 to 的 keyframe,瀏覽器會建構一個 100% 的 keyframe。

/* 假設原先設定是 background-color:red */
@keyframes animation {
50% {
background-color: green;
}
}

/* 瀏覽器會自動建構 */
@keyframes animation {
0% {
background-color: red;
}
50% {
background-color: green;
}
100% {
background-color: red;
}
}
  • 相同的 keyframe 可以歸類為一起
@keyframes animation {
0%,
100% {
background-color: red;
}

50% {
background-color: green;
}
}

class

動畫的使用其中一個是常被設計成 CSS class,再使用 JavaScript 或 jQuery 新增或刪除。

position

使用到 top、right、bottom、left 作為動畫 keyframe 裡面的屬性時,要先確認方框元素有沒有 position。

display:none

display:none 會中斷動畫的播放,並在下次設定 display:block 或其他不為 none 的值時,動畫會重頭再跑一次,而不會接續在中斷點。