經過定義一段動畫中的關鍵點、關鍵狀態來建立動畫。@Keyframes
相比transition
對動畫過程和細節有更強的控制。css
過渡動畫是兩個狀態間的變化,幀動畫能夠處理動畫過程當中不一樣時間的細節變化,html
對過渡動畫理解後再學習習幀動畫會很是容易,也能夠把幀動畫理解爲多個幀之間的過渡動畫。ide
一句話,幀動畫是CSS中的大殺器,你應該充分的瞭解並掌握它。函數
使用@keyframes
規則配置動畫中的各個幀學習
from 表示起始點flex
to表示終點動畫
可使用百分數如 20% 表明動畫運行到20%處網站
下面使用 @keyframes
定義了動畫叫 radius
並配置了兩個幀動做from/to
,而後在main:hover div
中使用animation-name
引用了動畫並使用animation-duration
聲明執行三秒。spa
注意:動畫命名不要使用CSS關鍵字如
none
3d
能夠看到上面的動畫是從30%
的圓角過渡到了50%
的圓角,可是整個動畫的結束是瞬間結束,整個動畫並不完美。
不要着急,下面會介紹各類方法讓你的幀動畫爲所欲爲。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> *{ margin: 0; padding: 0; list-style: none; box-sizing: border-box; } body{ height: 100vh; width: 100vw; display: flex; justify-content: center; align-items: center; } main{ height: 200px; width: 200px; display: flex; justify-content: center; align-items: center; border: 1px solid #ddd; } div{ height: 100px; width: 100px; background: #5352ed; } main:hover div{ /* 一組幀的名字 */ animation-name: radius; /* 動畫時長 */ animation-duration: 3s; } @keyframes radius{ from{ border-radius: 30%; } to{ border-radius: 50%; } } </style> </head> <body> <main> <div></div> </main> </body> </html>
幀動畫須要定義在不一樣時間執行的動做,開始與結束可使用 form/to
或 0%/100%
聲明。
必須添加百分號,25%是正確寫法
時間點沒有順序要求,即100%寫在25%前也能夠
未設置
0%
與100%
時將使用元素原始狀態
你能夠這麼理解,目前所學的一組幀動畫它的運行應該是這樣的
初始狀態 ---> 0% 或者 from ---> 100% 或者 to ---> 初始狀態
因此如今看上面的動畫,就知道爲何看起來比較生硬了。
下面定義不一樣時間點來讓物體元素移動一圈,下例中能夠不設置from/to
系統將定義爲元素初始狀態。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> *{ margin: 0; padding: 0; list-style: none; box-sizing: border-box; } body{ height: 100vh; width: 100vw; display: flex; justify-content: center; align-items: center; } main{ height: 400px; width: 400px; display: flex; justify-content: flex-start; align-items: flex-start; border: 1px solid #ddd; } div{ height: 100px; width: 100px; background: #5352ed; } main:hover div{ /* 一組幀的名字 */ animation-name: move; /* 動畫時長 */ animation-duration: 3s; } @keyframes move{ /* 初始狀態 ---> 幀 ---> 初始狀態 */ 25%{ transform: translate(300px,0); } 50%{ transform: translate(300px,300px); } 75%{ transform: translate(0,300px); } } </style> </head> <body> <main> <div></div> </main> </body> </html>
時間點能夠動畫樣式同樣時能夠一塊兒聲明,下面將25%/75%背景一塊兒聲明。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> *{ margin: 0; padding: 0; list-style: none; box-sizing: border-box; } body{ height: 100vh; width: 100vw; display: flex; justify-content: center; align-items: center; } main{ height: 400px; width: 400px; display: flex; justify-content: flex-start; align-items: flex-start; border: 1px solid #ddd; } div{ height: 100px; width: 100px; background: #5352ed; } main:hover div{ /* 一組幀的名字 */ animation-name: move; /* 動畫時長 */ animation-duration: 3s; } @keyframes move{ /* 初始狀態 ---> 幀 ---> 初始狀態 */ 25%{ transform: translate(300px,0); } 50%{ transform: translate(300px,300px); } 75%{ transform: translate(0,300px); } 25%,75%{ background: #ff4757; } 50%,100%{ background: #5352ed; } } </style> </head> <body> <main> <div></div> </main> </body> </html>
使用animation-name
規則能夠在元素身上同時使用多個動畫。
使用多個動畫時用逗號分隔多個
動畫有相同屬性時,後面動畫的屬性優先使用
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> *{ margin: 0; padding: 0; list-style: none; box-sizing: border-box; } body{ height: 100vh; width: 100vw; display: flex; justify-content: center; align-items: center; } main{ height: 400px; width: 400px; display: flex; justify-content: flex-start; align-items: flex-start; border: 1px solid #ddd; } div{ height: 100px; width: 100px; background: #5352ed; } main:hover div{ /* 一組幀的名字 可使用多組幀*/ animation-name: move,radius; /* 動畫時長 */ animation-duration: 3s; } @keyframes move{ /* 初始狀態 ---> 幀 ---> 初始狀態 */ 25%{ transform: translate(300px,0); } 50%{ transform: translate(300px,300px); } 75%{ transform: translate(0,300px); } /* 相同設置,前者不生效 */ 25%,75%{ background: #ff4757; } 50%,100%{ background: #5352ed; } } @keyframes radius{ 25%{ border-radius: 50%; } 50%{ border-radius: 30%; } 75%{ border-radius: 50%; } /* 相同設置後者覆蓋前者,因此移動時的顏色會變爲下面兩種 */ 25%,75%{ background: #ffa502; } 50%,100%{ background: #2ed573; } } </style> </head> <body> <main> <div></div> </main> </body> </html>
使用 animation-duration
能夠聲明動畫播放的時間,即把全部幀執行一遍所須要的時間。
可使用m秒,ms毫秒時間單位
可爲不一樣動畫單獨設置執行時間
若是動畫數量大於時間數量,將從新從時間列表中計算 。 如一個動畫有Move,Radius,Background 而時間是1s,2s,那麼Move的時間是1s,Radius的時間是2s,Background的時間從頭開始數,又是1s.
以下圖的過渡時間,圓角是六秒完成,背景色是四秒完成,移動是兩秒完成,可是他們的開始時間都是同樣的。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> *{ margin: 0; padding: 0; list-style: none; box-sizing: border-box; } body{ height: 100vh; width: 100vw; display: flex; justify-content: center; align-items: center; } main{ height: 400px; width: 400px; display: flex; justify-content: center; align-items: flex-start; border: 1px solid #ddd; } div{ height: 100px; width: 100px; background: #5352ed; } main:hover div{ /* 一組幀的名字 可使用多組幀*/ animation-name: radius,background,move; /* 動畫時長 圓角是六秒完成,背景色是四秒完成,移動是兩秒完成,可是他們的開始時間都是同樣的 */ animation-duration: 6s,4s,2s; /* 將動畫停留在最後一幀 */ animation-fill-mode: forwards; } @keyframes radius{ to{ border-radius: 50%; } } @keyframes background{ to{ } } @keyframes move{ to{ transform: translate(0,150px); } } </style> </head> <body> <main> <div></div> </main> </body> </html>
不是全部css屬性都有過渡效果,
如何理解中間值?
好比,一個元素的寬度從100px變爲200px,那麼它們之間就有中間值。
而一個元素的邊框樣式從實心線變爲虛心線,他們就沒有中間值。
看下面這張圖,從實心線變爲虛心線是瞬間變化,而背景顏色的改變倒是跟着動畫時間來進行漸變的。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> *{ margin: 0; padding: 0; list-style: none; box-sizing: border-box; } body{ height: 100vh; width: 100vw; display: flex; justify-content: center; align-items: center; } main{ height: 400px; width: 400px; display: flex; justify-content: center; align-items: center; border: 1px solid #ddd; } div{ height: 200px; width: 200px; background: #5352ed; /* 添加實心線 */ border: 15px solid red; } main:hover div{ /* 一組幀的名字 可使用多組幀*/ animation-name: border-style,background; /* 動畫時長 */ animation-duration: 2s; /* 將動畫停留在最後一幀 */ animation-fill-mode: forwards; } @keyframes border-style{ to{ border:15px dotted red ; } } @keyframes background{ to{ } } </style> </head> <body> <main> <div></div> </main> </body> </html>
能夠看下下面這個例子,左邊的塊from
與to
設置的尺寸單位沒有中間值,因此是瞬間變大。
而右邊塊的from
與to
設置的尺寸單位是具備中間值的,因此是跟隨動畫時間進行漸變。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> * { margin: 0; padding: 0; list-style: none; box-sizing: border-box; } body { height: 100vh; width: 100vw; display: flex; justify-content: center; align-items: center; } main { height: 400px; width: 400px; display: flex; justify-content: space-evenly; align-items: center; border: 1px solid #ddd; } main div:nth-child(1) { background: #5352ed; } main div:nth-child(2) { background: #ff4757; } main:hover div:nth-child(1) { /* 一組幀的名字 可使用多組幀*/ animation-name: size-percentage; /* 動畫時長 */ animation-duration: 2s; /* 將動畫停留在最後一幀 */ animation-fill-mode: forwards; } main:hover div:nth-child(2) { /* 一組幀的名字 可使用多組幀*/ animation-name: size-px; /* 動畫時長 */ animation-duration: 2s; /* 將動畫停留在最後一幀 */ animation-fill-mode: forwards; } @keyframes size-percentage { from { width: 200px; height: 200px; } /* px 與 % 之間沒有中間值,因此是瞬間出現 */ to { width: 50%; height: 50%; } } @keyframes size-px { from { width: 100px; height: 100px; } /* 有中間值,跟隨動畫時間進行漸變 */ to { width: 200px; height: 200px; } } </style> </head> <body> <main> <div></div> <div></div> </main> </body> </html>
使用animation-iteration-count
規則設置動畫重複執行次數,能夠給一個數字。當設置值爲 infinite
表示無限循環執行。
可同時設置元素的多個動畫重複,使用逗號分隔
若是動畫數量大於重複數量定義,後面的動畫將從新計算重複
以下面這個案例,移動的次數是一次,而變化圓角是無限次。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> *{ margin: 0; padding: 0; list-style: none; box-sizing: border-box; } body{ height: 100vh; width: 100vw; display: flex; justify-content: center; align-items: center; } main{ height: 400px; width: 400px; display: flex; justify-content: flex-start; align-items: flex-start; border: 1px solid #ddd; } div{ height: 100px; width: 100px; background: #5352ed; } main:hover div{ /* 一組幀的名字 可使用多組幀*/ animation-name: move,radius; /* 動畫時長 */ animation-duration: 3s; /* 表明移動只走一遍,隨後就不斷的圓角變化,進入死循環 */ animation-iteration-count: 1,infinite; } @keyframes move{ /* 初始狀態 ---> 幀 ---> 初始狀態 */ 25%{ transform: translate(300px,0); } 50%{ transform: translate(300px,300px); } 75%{ transform: translate(0,300px); } /* 相同設置,前者不生效 */ 25%,75%{ background: #ff4757; } 50%,100%{ background: #5352ed; } } @keyframes radius{ 25%{ border-radius: 50%; } 50%{ border-radius: 30%; } 75%{ border-radius: 50%; } /* 相同設置後者覆蓋前者,因此移動時的顏色會變爲下面兩種 */ 25%,75%{ background: #ffa502; } 50%,100%{ background: #2ed573; } } </style> </head> <body> <main> <div></div> </main> </body> </html>
使用循環動畫繪製心動效果。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <link rel="stylesheet" href="//at.alicdn.com/t/font_1953712_q6h4xm8p2jc.css" type="text/css"> <style> *{ margin: 0; padding: 0; list-style: none; box-sizing: border-box; } body{ height: 100vh; width: 100vw; display: flex; justify-content: center; align-items: center; } main{ height: 400px; width: 400px; display: flex; justify-content: center; align-items: center; border: 1px solid #ddd; } main i.iconfont{ font-size: 100px; color: red; } main:hover i{ /* 添加一組幀動畫 */ animation-name: xin; /* 時間 */ animation-duration: .5s; /* 循環次數 死循環 */ animation-iteration-count: infinite; } @keyframes xin { to{ opacity: .5; font-size: 120px; } 20%{ opacity: .6; font-size: 130px; } 40%{ opacity: .7; font-size: 140px; } 60%{ opacity: .8; font-size: 150px; } 80%{ opacity: .9; font-size: 160px; } to{ opacity: 1; font-size: 140px; } } </style> </head> <body> <main> <i class="iconfont icon-xin"></i> </main> </body> </html>
使用 animation-direction
控制動畫運行的方向。
選項 | 說明 |
---|---|
normal | 從0%到100%運行動畫 |
reverse | 從100%到0%運行動畫 |
alternate | 先從0%到100%,而後從100%到0% |
alternate-reverse | 先從100%到0%,而後從0%到100% |
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <link rel="stylesheet" href="//at.alicdn.com/t/font_1953712_q6h4xm8p2jc.css" type="text/css"> <style> * { margin: 0; padding: 0; list-style: none; box-sizing: border-box; } body { height: 100vh; width: 100vw; display: flex; justify-content: center; align-items: center; } main { height: 400px; width: 800px; display: flex; justify-content: space-evenly; align-items: center; border: 1px solid #ddd; } main i.iconfont { font-size: 100px; color: red; position: relative; } main:hover i { /* 添加一組幀動畫 */ animation-name: xin; /* 時間 */ animation-duration: .5s; /* 循環次數 死循環 */ animation-iteration-count: infinite; } main i:nth-child(1):after { content: "normal"; font-size: 15px; color: white; position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); } main i:nth-child(2):after { content: "normal-reverse"; font-size: 15px; color: white; position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); } main i:nth-child(3):after { content: "alternate"; font-size: 15px; color: white; position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); } main i:nth-child(4):after { content: "alternate-reverse"; font-size: 15px; color: white; position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); } main:hover i:nth-child(1) { /* 0-100 */ animation-direction: normal; } main:hover i:nth-child(2) { /* 100-0 */ animation-direction: reverse; } main:hover i:nth-child(3) { /* 0-100 100-0 */ animation-direction: alternate; } main:hover i:nth-child(4) { /* 100-0 0-100 */ animation-direction: alternate-reverse; } @keyframes xin { to { opacity: .5; font-size: 120px; } 20% { opacity: .6; font-size: 130px; } 40% { opacity: .7; font-size: 140px; } 60% { opacity: .8; font-size: 150px; } 80% { opacity: .9; font-size: 160px; } to { opacity: 1; font-size: 140px; } } </style> </head> <body> <main> <i class="iconfont icon-xin"></i> <i class="iconfont icon-xin"></i> <i class="iconfont icon-xin"></i> <i class="iconfont icon-xin"></i> </main> </body> </html>
alternate-reverse
是100-0 0-100,所以很是適合用來作彈跳球。
咱們先把球和陰影都定義在下方,而後使用alternate-reverse
將球轉移到上方便可。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <link rel="stylesheet" href="//at.alicdn.com/t/font_1953712_q6h4xm8p2jc.css" type="text/css"> <style> * { margin: 0; padding: 0; list-style: none; box-sizing: border-box; } body { height: 100vh; width: 100vw; display: flex; justify-content: center; align-items: center; } main { height: 400px; width: 400px; display: flex; flex-flow: column; justify-content: flex-end; align-items: center; border: 1px solid #ddd; } main div { height: 100px; width: 100px; background: linear-gradient(45deg, #7bed9f, #2ed573, #1e90ff, #3742fa); border-radius: 50%; } main section { width: 140px; height: 20px; background: #2f3542; border-radius: 75%; /* 高斯模糊 */ filter: blur(3px); } main:hover div { /* 添加一組幀動畫 */ animation-name: beat; /* 動畫時間 */ animation-duration: 1s; /* 運動方式 100-0 0-100 */ animation-direction: alternate-reverse; /* 死循環 */ animation-iteration-count: infinite; } main:hover section { /* 添加一組幀動畫 */ animation-name: size; /* 動畫時間 */ animation-duration: 1s; /* 運動方式 100-0 0-100 */ animation-direction: alternate-reverse; /* 死循環 */ animation-iteration-count: infinite; } @keyframes beat { from{ background: linear-gradient(90deg, #7bed9f, #2ed573, #1e90ff, #3742fa); width: 140px; } to { transform: translateY(-280px); } } @keyframes size{ to{ width: 70px; } } </style> </head> <body> <main> <div></div> <section></section> </main> </body> </html>
使用 animation-delay
規則定義動畫等待多長時間後執行。
咱們能夠爲多個動畫指定不一樣的延遲時間,與動畫時間的使用規則相同。
延遲動畫 圓角3s後執行,背景色2s後執行,移動1s後執行
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> *{ margin: 0; padding: 0; list-style: none; box-sizing: border-box; } body{ height: 100vh; width: 100vw; display: flex; justify-content: center; align-items: center; } main{ height: 400px; width: 400px; display: flex; justify-content: center; align-items: flex-start; border: 1px solid #ddd; } div{ height: 100px; width: 100px; background: #5352ed; } main:hover div{ /* 一組幀的名字 可使用多組幀*/ animation-name: radius,background,move; /* 動畫時長 */ animation-duration: 2s; /* 延遲動畫 圓角3s後執行,背景色2s後執行,移動1s後執行*/ animation-delay:3s,2s,1s; /* 將動畫停留在最後一幀 */ animation-fill-mode: forwards; } @keyframes radius{ to{ border-radius: 50%; } } @keyframes background{ to{ background-color: #ffa502; } } @keyframes move{ to{ transform: translate(0,150px); } } </style> </head> <body> <main> <div></div> </main> </body> </html>
使用animation-timing-function
來控制動畫速率
值 | 描述 |
---|---|
linear | 規定以相同速度開始至結束的過渡效果(等於 cubic-bezier(0,0,1,1))。 |
ease | 開始慢,而後快,慢下來,結束時很是慢(cubic-bezier(0.25,0.1,0.25,1))默認值。 |
ease-in | 開始慢,結束快(等於 cubic-bezier(0.42,0,1,1)) |
ease-out | 開始快,結束慢(等於 cubic-bezier(0,0,0.58,1)) |
ease-in-out | 中間快,兩邊慢(等於 cubic-bezier(0.42,0,0.58,1)) |
cubic-bezier(n,n,n,n) | 在 cubic-bezier 函數中定義本身的值 |
能夠在幀中單獨定義,將影響當前幀的速率
其實不論是linear
或者是ease
都是由貝塞爾曲線來完成的。
咱們須要設置四個值 cubic-bezier(<x1>, <y1>, <x2>, <y2>)
來控制曲線速度,可在
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> *{ margin: 0; padding: 0; list-style: none; box-sizing: border-box; } body{ height: 100vh; width: 100vw; display: flex; justify-content: center; align-items: center; } main{ height: 400px; width: 400px; display: flex; justify-content: space-evenly; align-items: flex-end; border: 1px solid #ddd; } div{ padding: 10px; height: 100%; width: 25%; text-align: center; background: #ff4757 content-box; color: white; } main:hover div{ /* 一組幀的名字 可使用多組幀*/ animation-name: move; /* 動畫時長 */ animation-duration: 3s; /* 重複動畫 死循環 */ animation-iteration-count: infinite; } main:hover div:nth-child(1){ animation-timing-function: linear; } main:hover div:nth-child(2){ animation-timing-function: ease; } main:hover div:nth-child(3){ animation-timing-function: ease-in; } main:hover div:nth-child(4){ animation-timing-function: ease-out; } main:hover div:nth-child(5){ animation-timing-function: ease-in-out; } @keyframes move{ to{ height: 0; } } </style> </head> <body> <main> <div>linear</div> <div>ease</div> <div>ease-in</div> <div>ease-out</div> <div>ease-in-out</div> </main> </body> </html>
ease-out
是開始快,結束慢,而ease-in
是結束快,開始慢。所以這兩個組合作彈跳小球恰好。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <link rel="stylesheet" href="//at.alicdn.com/t/font_1953712_q6h4xm8p2jc.css" type="text/css"> <style> * { margin: 0; padding: 0; list-style: none; box-sizing: border-box; } body { height: 100vh; width: 100vw; display: flex; justify-content: center; align-items: center; } main { height: 400px; width: 400px; display: flex; flex-flow: column; justify-content: space-between; align-items: center; border: 1px solid #ddd; } main div { height: 100px; width: 100px; background: linear-gradient(45deg, #eccc68, #ffa502, #ff6b81, #ff4757); border-radius: 50%; } main section { width: 70px; height: 20px; background: #2f3542; border-radius: 75%; /* 高斯模糊 */ filter: blur(3px); } main:hover div { /* 添加一組幀動畫 */ animation-name: beat; /* 動畫時間 */ animation-duration: 3s; /* 死循環 */ animation-iteration-count: infinite; } main:hover section { /* 添加一組幀動畫 */ animation-name: size; /* 動畫時間 */ animation-duration: 3s; /* 死循環 */ animation-iteration-count: infinite; } @keyframes beat { 0% { background: linear-gradient(60deg, #eccc68, #ffa502, #ff6b81, #ff4757); transform: translateY(0px); animation-timing-function: ease-in; width: 100px; } 30% { background: linear-gradient(120deg, #eccc68, #ffa502, #ff6b81, #ff4757); transform: translateY(50px); animation-timing-function: ease-in; width: 100px; } 60% { background: linear-gradient(240deg, #eccc68, #ffa502, #ff6b81, #ff4757); transform: translateY(100px); animation-timing-function: ease-in; width: 100px; } 80% { background: linear-gradient(300deg, #eccc68, #ffa502, #ff6b81, #ff4757); transform: translateY(150px); animation-timing-function: ease-in; width: 100px; } 95% { background: linear-gradient(340deg, #eccc68, #ffa502, #ff6b81, #ff4757); transform: translateY(200px); animation-timing-function: ease-in; width: 100px; } 15%, 45%, 70%, 85%, 100% { width: 140px; transform: translateY(280px); animation-timing-function: ease-out; } } @keyframes size { 0% { width: 80px; } 30% { width: 85px; } 60% { width: 95px; } 80% { width: 110px; } 95% { width: 120px; } 15%, 45%, 70%, 85%, 100% { width: 140px; } } </style> </head> <body> <main> <div></div> <section></section> </main> </body> </html>
這個須要用到盒子陰影,一個元素能夠有多個陰影。
盒子陰影的設置規則以下:
水平偏移度/垂直偏移度/模糊度/顏色
對於顏色而言可使用currentColor
來獲取當前盒子的color
屬性。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <link rel="stylesheet" href="//at.alicdn.com/t/font_1953712_q6h4xm8p2jc.css" type="text/css"> <style> * { margin: 0; padding: 0; list-style: none; box-sizing: border-box; } body { height: 100vh; width: 100vw; display: flex; justify-content: center; align-items: center; } main { height: 400px; width: 400px; display: flex; justify-content: center; align-items: center; border: 1px solid #ddd; } main button { height: 40px; width: 100px; background-color: #747d8c; color: white; display: flex; justify-content: center; align-items: center; } main button::after { content: ''; display: inline-block; height: 3px; width: 3px; margin-left: 5px; } /* Js中可換成點擊事件 */ button:hover::after { /* 添加一組幀動畫 */ animation-name: point; /* 動畫時間 */ animation-duration: 2s; /* 死循環 */ animation-iteration-count: infinite; /* 動畫速率 */ animation-timing-function: linear; } @keyframes point { 60%{ box-shadow: none; } 30% { box-shadow: 3px 0 currentColor; } 60% { box-shadow: 3px 0 currentColor, 9px 0 currentColor; } to { box-shadow: 3px 0 currentColor, 9px 0 currentColor, 15px 0 currentColor; } } </style> </head> <body> <main> <button>提交</button> </main> </body> </html>
過渡使用階梯化呈現,有點像現實生活中的機械舞,下面是把過渡分3步完成。
選項 | 說明 |
---|---|
steps(n,start) | 設置n個時間點,第一時間點變化狀態 |
steps(n,end) | 設置n個時間點,第一時間點初始狀態 |
step-start | 等於steps(1,start),能夠理解爲從下一步開始 |
step-end | 等於steps(1,end),能夠理解爲從當前步開始 |
start
老是先走,end
老是後走。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> *{ margin: 0; padding: 0; box-sizing: border-box; } body{ height: 100vh; width: 100vw; display: flex; justify-content: center; align-items: center; } main{ height: 400px; width: 800px; display: flex; border:1px solid #ddd; position: relative; } main div{ width: 200px; height: 100%; border: 1px solid #ddd; } main::after{ content: "START"; height: 30%; width: 25%; background: #ff4757; color: #fff; font-size: 2em; position: absolute; top: 0; display: flex; justify-content: center; align-items: center; } main::before{ content: "END"; height: 30%; width: 25%; background: #70a1ff; color: #fff; font-size: 2em; position: absolute; bottom: 0; display: flex; justify-content: center; align-items: center; } main:hover::after{ /* 添加一組動畫幀 */ animation-name: move; /* 步進動畫,3步 */ animation-timing-function: steps(3,start); /* 動畫時長2s */ animation-duration: 2s; } main:hover::before{ /* 添加一組動畫幀 */ animation-name: move; /* 步進動畫,3步 */ animation-timing-function: steps(3,end); /* 動畫時長2s */ animation-duration: 2s; } @keyframes move{ to{ transform: translateX(600px); } } </style> </head> <body> <main> <div></div> <div></div> <div></div> <div></div> </main> </body> </html>
使用 animation-play-state
能夠控制動畫的暫停與運行。
選項 | 說明 |
---|---|
paused | 鼠標放上時暫停 |
running | 鼠標放上時運行 |
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> * { padding: 0; margin: 0; } body { width: 100vw; height: 100vh; display: flex; justify-content: center; align-items: center; background: #2c3e50; } main { width: 400px; border: solid 5px #ddd; border-width: 5px 0 5px 0; overflow: hidden; position: relative; } main:hover section { animation-play-state: paused; } main:hover ul::before { animation-play-state: paused; } section { width: 1600px; height: 200px; display: flex; flex-direction: row; animation-name: slide; animation-duration: 4s; animation-iteration-count: infinite; animation-timing-function: steps(4, end); } section div { width: 400px; height: 200px; overflow: hidden; } section div img { width: 100%; } ul { width: 200px; position: absolute; list-style: none; display: flex; justify-content: center; align-items: center; z-index: 3; bottom: 20px; left: 50%; transform: translateX(-50%); } ul li { font-size: 2em; font-weight: bold; color: white; width: 50px; height: 50px; border-radius: 50%; border: solid 3px transparent; box-sizing: border-box; display: flex; justify-content: center; align-items: center; z-index: 2; background: rgba(0, 0, 0, .3); box-shadow: 0 0 3px rgba(0, 0, 0, 1); } ul::before { content: ''; width: 50px; height: 50px; border-radius: 50%; position: absolute; background: #e74c3c; left: 0; animation-name: num; animation-duration: 4s; animation-iteration-count: infinite; animation-timing-function: steps(4, end); z-index: 1; } @keyframes slide { from { transform: translateX(0px); } to { transform: translateX(-100%); } } @keyframes num { 100% { transform: translateX(200px); } } </style> </head> <body> <main> <section> <div> <img src="1.jpg" alt=""> </div> <div> <img src="2.jpg" alt=""> </div> <div> <img src="3.jpg" alt=""> </div> <div> <img src="4.jpg" alt=""> </div> </section> <ul> <li>1</li> <li>2</li> <li>3</li> <li>4</li> </ul> </main> </body> </html>
animation-fill-mode
用於定義動畫播放結束後的處理模式,是回到原來狀態仍是中止在動畫結束狀態。
選項 | 說明 |
---|---|
none | 須要等延遲結束,起始幀屬性才應用 |
backwards | 動畫效果在起始幀,不等延遲結束 |
forwards | 結束後停留動畫的最後一幀 |
both | 包含backwards與forwards規則,即動畫效果在起始幀,不等延遲結束,而且在結束後中止在最後一幀 |
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> * { margin: 0; padding: 0; box-sizing: content-box; } body{ display: flex; justify-content: center; align-items: center; height: 100vh; width: 100vw; } main{ display: flex; justify-content: space-evenly; align-items: center; height: 200px; width: 800px; border: 1px solid #ddd; } div{ height: 80px; width: 200px; background: #000 content-box; padding: 10px; display: flex; justify-content: space-evenly; align-items: center; color: #fff; position: relative; } main:hover div{ /* 添加一組幀動畫 */ animation-name: background; /* 運行時間 */ animation-duration: 3s; /* 延遲時間 */ animation-delay: 2s; } main div:nth-child(1)::before{ content: "等待延遲 不停留最後一幀"; display: flex; justify-content: space-evenly; align-items: center; color: red; font-weight: bolder; position: absolute; top: -20px; } main div:nth-child(2)::before{ content: "不等待延遲 不停留最後一幀 "; display: flex; justify-content: space-evenly; align-items: center; color: red; font-weight: bolder; position: absolute; top: -20px; } main div:nth-child(3)::before{ content: "等待延遲 停留最後一幀 "; display: flex; justify-content: space-evenly; align-items: center; color: red; font-weight: bolder; position: absolute; top: -20px; } main div:nth-child(4)::before{ content: "不等待延遲 停留最後一幀 "; display: flex; justify-content: space-evenly; align-items: center; color: red; font-weight: bolder; position: absolute; top: -20px; } main:hover div:nth-child(1){ animation-fill-mode: none; } main:hover div:nth-child(2){ animation-fill-mode: backwards; } main:hover div:nth-child(3){ animation-fill-mode: forwards; } main:hover div:nth-child(4){ animation-fill-mode: both; } @keyframes background{ from{ background-color: #ff6348; } 30%{ background-color: #ffa502; } 60%{ background-color: #eccc68; } to{ background-color: #2ed573; } } </style> </head> <body> <main> <div>none</div> <div>backwards</div> <div>forwards</div> <div>both</div> </main> </body> </html>
和CSS中的其餘屬性同樣,可使用animation
組合定義幀動畫。animation 屬性是一個簡寫屬性,用於設置六個動畫屬性:
animation-name 幀動畫名字
animation-duration 幀動畫運行時間
animation-timing-function 幀動畫速率
animation-delay 幀動畫播放狀態(暫停/運行)
animation-iteration-count 幀動畫循環次數
animation-direction 延遲時間
必須存在 animation-duration