CSS 動畫教程:初學者完整指南
已發表: 2022-02-07這是針對初學者的完整語法指南和交互式 CSS 動畫教程。 使用它作為參考來學習 CSS 動畫規範的不同部分。
在過去的 10 年中,瀏覽器性能取得了長足的進步。 由於潛在的渲染和性能問題,向網頁添加交互式動畫過去更具挑戰性。 但如今,CSS 動畫可以更自由地使用,並且與網格或 flexbox 等 CSS 功能相比,語法通常更容易學習。
W3C CSS 動畫規範中有不同的特性。 有些比其他更容易使用。 本 CSS 關鍵幀動畫教程將介紹所有語法,包括每個不同的屬性。 我將包含交互式演示,以幫助您掌握 CSS 動畫的可能性。
@keyframes 語法
每個 CSS 動畫都有兩個部分:一個或多個animation-*
屬性以及一組使用@keyframes
規則定義的動畫關鍵幀。 讓我們詳細了解構建@keyframes
規則集的內容。
語法如下所示:
@keyframes moveObject 0% transform: translateX(0); 50% transform: translateX(300px); 100% transform: translateX(300px) scale(1.5);
如此處所示, @keyframes
at-rule 包括三個基本部分:
-
@keyframes
規則後跟自定義動畫名稱 - 一組包含所有關鍵幀的花括號
- 一個或多個關鍵幀,每個關鍵幀都有一個百分比,後跟一個用花括號括起來的規則集
在我們的 CSS 動畫教程的第一個示例中,我使用名稱moveObject
定義了我的動畫。 這可以是我想要的任何名稱,區分大小寫,並且必須遵守 CSS 中的自定義標識符規則。 此自定義名稱必須與animation-name
屬性中使用的名稱匹配(稍後討論)。
在我的示例中,您會注意到我使用百分比來定義動畫中的每個關鍵幀。 如果我的動畫包含等於0%
和100%
的關鍵幀,我可以選擇使用from
和to
關鍵字:
@keyframes moveObject from transform: translateX(0); 50% transform: translateX(300px); to transform: translateX(300px) scale(1.5);
以下交互式 CodePen 在一個實時示例中使用上述語法:
在演示中,我包含了一個重置動畫的按鈕。 稍後我將解釋為什麼需要這樣做。 但是現在,只要知道這個動畫包括三個關鍵幀,它們代表這個動畫序列中的步驟:開始、50% 步驟和結束(即 0%、50% 和 100%)。 其中每一個都使用所謂的關鍵幀選擇器和花括號來定義該步驟的屬性。
關於@keyframes
語法的一些注意事項:
- 您可以按您想要的任何順序放置關鍵幀規則集,瀏覽器仍將按照其百分比確定的順序運行它們
- 您可以省略 0% 和 100% 關鍵幀,瀏覽器將根據動畫元素的現有樣式自動確定這些關鍵幀
- 如果存在具有不同規則集的重複關鍵幀(例如,具有不同變換值的 20% 的兩個關鍵幀),瀏覽器將使用最後一個
- 您可以使用逗號在單個關鍵幀選擇器中定義多個關鍵幀:
10%, 30% ...
-
!important
關鍵字使任何屬性值無效,因此不應在關鍵幀規則集中的屬性上使用它
現在您已經很好地理解了本 CSS 動畫教程中的@keyframes
語法,讓我們來看看在動畫元素上定義的不同動畫屬性。
我們將要介紹的動畫屬性:
動畫名稱屬性
如前所述,您創建的每個 CSS 動畫都必須有一個出現在@keyframes
語法中的名稱。 此名稱必須與使用animation-name
相同。
使用上一個演示中的 CSS,語法如下所示:
.box animation-name: moveObject;
同樣,我定義的自定義名稱也必須作為@keyframes
at-rule 的名稱存在——否則這個名稱將不起作用。 你可以把它想像成 JavaScript 中的函數調用。 函數本身是代碼的@keyframes moveObject
部分,而函數調用是animation-name: moveObject
。
關於animation-name
一些事情:
-
animation-name
的初始值為none
,這意味著沒有關鍵幀處於活動狀態。 這可以用作一種“切換”來停用動畫。 - 您選擇的名稱區分大小寫,可以包含字母、數字、下劃線和連字符。
- 名稱中的第一個字符必須是字母或連字符,但只能是單個連字符。
- 名稱不能是保留字,如
unset
、initial
或inherit
。
動畫持續時間屬性
毫不奇怪, animation-duration
屬性定義了動畫從開始到結束運行一次所需的時間。 該值可以以秒或毫秒為單位指定,如下所示:
.box animation-duration: 2s;
以上將等同於以下內容:
.box animation-duration: 2000ms;
您可以在下面的 CodePen 演示中看到animation-duration
屬性的作用。 在此演示中,您可以選擇希望動畫持續多長時間。 嘗試以秒或毫秒為單位輸入各種值,然後使用“Animate the Box”按鈕運行動畫。
如果您在單位中使用小數字和ms
,您甚至可能不會注意到任何移動。 如果您使用毫秒,請嘗試設置更高的數字。
關於使用animation-duration
一些注意事項:
- 負值無效
- 必須包含單位,即使持續時間設置為
0s
(初始值) - 您可以使用小數值(例如
0.8s
)
動畫計時功能屬性
animation-timing-function
,其含義不如前兩個屬性明顯,用於定義 CSS 動畫進行的方式。 這可能不是最清楚的解釋,但語法可能有助於澄清。
聲明如下所示:
.box animation-timing-function: linear;
此屬性接受以下關鍵字值:
-
ease
(初始值) -
ease-in
-
ease-out
-
ease-in-out
-
linear
-
step-start
-
step-end
大多數值通過它們的名稱相對容易掌握,但是您可以通過使用以下交互式演示來了解它們的不同之處:
使用選擇輸入來選擇七個關鍵字值之一。 請注意, ease-*
以各種方式“緩和”動畫。 線性值自始至終都是一致的。
animation-timing-function
屬性還接受以下函數:
-
cubic-bezier()
- 接受四個數字值作為參數,用逗號分隔 steps()
– 接受兩個值作為參數,一個數字和一個“跳轉項”,用逗號分隔
關鍵字值step-start
和step-end
分別等效於值steps(1, jump-start)
和steps(1, jump-end)
。
至於cubic-bezier()
,下面的交互式演示可能會幫助您更好地理解該函數:
請注意,該演示允許您在cubic-bezier()
函數中設置四個參數。 其中兩個參數可以是負數,兩個被限制為 0 和 1 之間的十進制值。有關這些類型的計時函數如何工作的正確解釋,您可以查看這篇文章或這個交互式工具。
另一方面, steps()
函數接受兩個參數:
- 一個整數,表示沿動畫的單個循環相等的“停止”。
- 一個稱為“jumpterm”的可選關鍵字,用於確定動畫是否以特定間隔“保持”
同樣,交互式演示應該可以幫助您掌握這些跳轉術語的工作原理:
嘗試選擇一個整數和一個跳轉項(或嘗試不使用跳轉項)以查看不同的關鍵字與不同的整數值有何不同。 顯然負整數是允許的,但我看不出 0 和任何負值之間有任何區別。
動畫迭代計數屬性
在某些情況下,如果動畫運行一次,您會很高興,但有時您希望動畫運行多次。 animation-iteration-count
屬性允許您通過接受一個正數來執行此操作,該正數表示您希望動畫運行的次數:

.box animation-iteration-count: 3;
animation-iteration-count
的初始值為1
,但您也可以使用關鍵字infinite
(不言自明)或使用小數值。 小數值將在小數運行中部分運行動畫:
.box animation-iteration-count: 3.5;
上面的代碼在動畫中運行了三遍半。 也就是說,三個完整的迭代,然後是一個在中途停止的最終迭代。
此屬性在與animation-direction
屬性(接下來討論)結合使用時最有用,因為僅從頭開始運行的動畫如果運行多次則不是非常有用。
您可以嘗試下面的演示,它允許您為迭代計數選擇一個小數值,這樣您就可以看到效果:
動畫方向屬性
正如上面這個 CSS 動畫教程中提到的, animation-direction
屬性與animation-iteration-count
配合得很好。 animation-direction
屬性允許您定義希望動畫播放的方向。 語法如下所示:
.box animation-direction: alternate;
您可以將該值設置為以下四個關鍵字之一:
-
normal
– 動畫在第一次迭代時向前播放(默認) -
reverse
– 動畫在第一次迭代時向後播放 alternate
- 動畫在第一次迭代中向前播放,然後在後續迭代中交替播放alternate-reverse
– 與alternate
相同,但在第一次迭代時向後播放
您可以使用下面的交互式演示嘗試具有不同迭代次數的不同值:
動畫播放狀態屬性
animation-play-state
屬性在靜態 CSS 環境中不是非常有用,但在編寫通過 JavaScript 甚至 CSS 交互的動畫時可能會派上用場。
此屬性接受兩個值: running
或paused
:
.box animation-direction: paused;
默認情況下,任何給定的動畫都處於“運行”狀態。 但是您可以使用 JavaScript 來切換屬性的值。 您甚至可以使用交互式 CSS 功能(例如:hover
或:focus
)將動畫更改為“暫停”狀態,這實際上將動畫凍結在當前迭代中的任何位置。
下面的交互式演示有一個無限運行的動畫,帶有兩個按鈕來“暫停”和“恢復”動畫。
動畫延遲屬性
一些動畫被設計為立即開始動畫,而另一些則可以從第一次迭代之前的輕微延遲中受益。 animation-delay
屬性允許您完成此操作。
.box animation-delay: 4s;
與其他基於時間的值一樣,您可以將animation-delay
設置為使用秒或毫秒的值。 您也可以使用小數值。
重要的是要注意延遲只發生在第一次迭代,而不是每次迭代。 您可以使用下面的交互式演示進行嘗試:
該演示為您提供了更改迭代值和延遲的選項,因此您可以看到延遲不會影響任何後續迭代 - 僅影響第一次。
使用此屬性的一種有趣方式是使用負值。 例如,使用上面的演示,嘗試將animation-delay
設置為-0.5s
。 您會注意到負延遲的工作方式幾乎就像在時間機器中前進一樣 - 動畫從中途開始而不是在開始時開始。
動畫填充模式屬性
我將在本 CSS 動畫教程中介紹的最後一個速記屬性是我在上一個演示中使用的屬性。 您會注意到,當動畫停止最後一次迭代時,框仍保留在原處。 這是使用animation-fill-mode
完成的。
.box animation-fill-mode: forwards;
此屬性設置動畫在執行之前和之後如何將樣式應用於目標元素。 這在概念上有點難以理解,所以我將介紹每個值的含義; 然後您可以使用交互式演示來比較這些值。
此屬性接受以下四個關鍵字值:
-
none
– 默認值,在執行之前或之後不應用樣式 forwards
– 保留動畫最後一個關鍵幀中應用的所有樣式backwards
- 或多或少與前一個值相反,它在開始執行但在動畫開始之前保留應用於動畫的樣式both
– 保留forwards
和backwards
的樣式
這個 CSS 動畫教程中的最後一個演示將使事情變得更清晰一些,但是在你真正了解它的作用以及它是如何實現它之前,這個演示可能需要大量的時間。
為方便起見,我已將所有演示添加到單個 CodePen 集合中。
您會注意到該演示允許您調整填充模式、延遲、方向和迭代次數,因為所有這些都會對外觀產生影響。 我還在第一個關鍵幀的動畫框中添加了不同的背景顏色,這再次有助於使填充模式值更加清晰。 如果您仍然不太了解animation-fill-mode
工作原理,您可以查看我寫的一篇較早的文章,該文章深入討論了animation-fill-mode
。
動畫速記屬性
在這個面向初學者的 CSS 動畫教程中,我介紹了八種不同的屬性,我鼓勵你使用長手。 這將使您更容易看到明確的值集。
一旦你對每個屬性有了很好的理解,你就可以選擇使用animation
速記屬性,它允許你在一個聲明中定義所有的速記屬性。
.box animation: moveObject 2s ease-in-out 3 reverse running 1.3s forwards;
老實說,一行中有很多信息。 如果聲明不包括所有屬性,但可能只包括其中的三個或四個,我建議使用速記。
如果您確實使用速記,則可以按您想要的任何順序放置值,但請注意以下規則:
- 定義時間的第一個值是
animation-duration
; 任何後續時間值都是animation-delay
。 - 如果關鍵字和
animation-name
之間存在衝突,則關鍵字值將優先出現,如果它首先出現。 - 任何省略的值都將回退到它們的初始狀態,就像任何 CSS 速記屬性一樣。
將多個動畫應用於單個元素
最後一個值得注意的功能是,您可以選擇通過逗號分隔動畫來將多個動畫應用於單個對象。
下面是一個使用速記的例子:
.box animation: moveObject 2s ease-in-out, fadeBox 3s linear;
在這裡,我定義了兩個不同的動畫,它們將映射到兩組不同的關鍵幀,但會應用於同一個對象。 同樣的代碼可以寫成:
.box animation-name: moveObject, fadeBox; animation-duation: 2s, 3s; animation-timing-function: ease-in-out, linear;
請注意每個屬性如何包含兩個用逗號分隔的值。 在這種情況下,速記幾乎肯定更容易閱讀和維護。
結束這個 CSS 動畫教程
如果你是一個 CSS 初學者,並且這個 CSS 動畫教程是你第一次嘗試在網頁上移動東西,我希望這節課足夠全面。 您甚至可以將 CSS 變量與動畫結合起來,使它們更加強大。
最後一個警告:適度使用動畫,並記住一些網絡用戶可能會受到閃爍顏色和其他快速移動對象的負面影響。
通過練習,構建 CSS 動畫的語法和概念會牢牢記住,而且你肯定會從在不同的演示中擺弄代碼中受益。