1. 程式人生 > 實用技巧 >CSS動畫基礎知識

CSS動畫基礎知識

CSS動畫就是通過CSS (Cascading Style Sheet,層疊樣式表)程式碼搭建的網頁動畫。它允許設計師和開發人員通過編輯網站的CSS程式碼來新增頁面動畫,從而輕鬆取代傳統動畫圖片或flash動畫的設計方式。

transition(過渡)和animation(動畫)是CSS3中的兩種動畫屬性。

transition強調過渡,是元素的一個或多個屬性發生變化時產生的過渡效果,同一個元素通過兩個不同的途徑獲取樣式,而第二個途徑當某種改變發生(例如hover)時才能獲取樣式,這樣就會產生過渡動畫。

animation強調流程與控制,對元素的一個或多個屬性的變化進行控制,可以有多個關鍵幀(animation 和@ keyframes結合使用)。

1.transition 屬性

transition 屬性是一個簡寫屬性,用於設定四個過渡屬性:

transition-property、transition-duration、transition-timing-function、transition-delay。

(1)transition-duration屬性。

transition-duration 屬性規定完成過渡效果需要花費的時間(以秒或毫秒計)。其格式為:

transition-duration: time;

屬性值time規定完成過渡效果需要花費的時間(以秒或毫秒計)。預設值是 0,意味著不會有效果。

若想得到動畫效果,需要指定transition-duration屬性,否則持續時間為0,transition不會有任何效果。

(2)transition-delay 屬性。

transition-delay 屬性規定過渡效果何時開始。其格式為:

transition-delay: time;

屬性值time規定在過渡效果開始之前需要等待的時間,以秒或毫秒計。

(3)transition-property屬性。

transition-property屬性指定CSS屬性的nametransition效果(transition效果時將會啟動指定的CSS屬性的變化)。其格式為:

transition-property: none |all | property;

其中,屬性值none表示沒有屬性會獲得過渡效果;屬性值all表示所有屬性都將獲得過渡效果;property 定義應用過渡效果的 CSS 屬性名稱列表,列表以逗號分隔。

(4)transition-timing-function 屬性。

transition-timing-function屬性指定切換效果的速度。此屬性允許一個過渡效果,以改變其持續時間的速度。其格式為:

transition-timing-function: linear|ease|ease-in|ease-out|ease-in-out|cubic-bezier(n,n,n,n);

各屬性值的功能描述如下:

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 函式中定義自己的值。可能的值是 0 至 1 之間的數值。

例1 transition 屬性的簡單應用。

先看一個簡單的例子,體會transition 屬性的應用。

在頁面中放置一個類名為container的層作為效果展示容器,在該層中再定義一個類名為move-box的層作為應用過渡效果的物件,HTML程式碼描述如下:

<div class="container">

<div class="move-box">

</div>

</div>

為兩個層定義CSS樣式如下:

.container

{

width: 300px;

height: 200px;

border: 4px solid rgba(255, 0, 0, 0.9);

}

.move-box

{

left:0;

width: 50px;

height: 50px;

position: relative;

background: rgb(0,0,255);

}

這樣,在頁面中會顯示如圖1所示的圖形。

圖1 兩個層在頁面中的顯示

為.containe層新增滑鼠懸停樣式規則,設定move-box層的left屬性值為250px,這樣當滑鼠懸停在圖1所示的紅色矩形框中,藍色正方形會移動到紅色矩形框的最右端。

.container:hover .move-box

{

left:250px;

}

但這個移動是瞬時完成的,沒有任何過渡效果,更談不上動畫了。為此,需要為這個移動的變化設定transition屬性。增加樣式規則如下:

.container .move-box

{

transition-duration: 2s;

}

此時,可以得到如圖2所示的藍色小正方形移動的動畫效果。當滑鼠懸停在紅色矩形框中時,藍色小正方形從左向右移動;當滑鼠移離時,藍色小正方形從右向左移動。

圖2 藍色小正方形移動:雙向過渡效果

完整的HTML程式碼如下。

<!DOCTYPE html>
<html>
<head>
<title>transition 屬性的簡單應用</title>
<style>
.container
{
     width: 300px;
     height: 200px;
     border: 4px solid rgba(255, 0, 0, 0.9);
}
.move-box
{
     left:0;
     width: 50px;
     height: 50px;
     position: relative;
     background: rgb(0,0,255);
}
.container .move-box
{
    transition-duration: 2s;
}
.container:hover .move-box
{
     left:250px; 
}
</style>
</head>
<body>
<div  class="container">
  <div class="move-box">
  </div>
</div>
</body>
</html>
View Code

在這個例子中,在.container .move-box 中設定了過渡動畫完成的時間為2秒鐘(transition-duration: 2s;),這樣在left屬性變化時會產生過渡動畫效果,而這種效果的產生有兩種途徑:一種是滑鼠在container上懸停, move-box的樣式從預設樣式到.container:hover的樣式,left屬性發生了變化,觸發了過渡效果; 一種是滑鼠移離container層,move-box的樣式從.container:hover的樣式回到預設樣式,left也變化了,因此也產生了過渡效果。這兩個方向上的過渡都是平滑不突兀的。

若將.container .move-box樣式定義中的transition-duration: 2s;移到.container:hover .move-box中,並刪除.container .move-box樣式定義,如下:

.container:hover .move-box

{

left:250px;

transition-duration: 2s;

}

此時,過渡動畫是單一方向上的,當滑鼠在container上懸停時, move-box的樣式從預設樣式到.container:hover的樣式,left屬性發生了變化,觸發了過渡效果; 當滑鼠移離container層,move-box的樣式從.container:hover的樣式回到預設樣式,left也變化了,但此時不是過渡動畫的方式,而是直接回到預設,看上去比較突兀和生硬。效果如圖3所示。

圖3 藍色小正方形移動:單一方向上有過渡效果

例1中的過渡動畫效果是通過改變動畫元素的left屬性,從而使得元素的位置發生改變而得到的。為了對選定元素進行更多的變換,可以應用transform屬性。

transform屬性應用於元素的2D或3D轉換。這個屬性允許將元素旋轉、縮放、移動、傾斜等。其基本使用格式為:

transform: none|transform-functions;

其中,屬性值none表示不進行轉換;屬性值transform-functions表示所採用的轉換函式,可應用的轉換函式和功能描述如下:

matrix(n,n,n,n,n,n) 定義 2D 轉換,使用六個值的矩陣。

matrix3d(n,n,n,n,n,n,n,n,n,n,n,n,n,n,n,n) 定義 3D 轉換,使用16個值的4x4矩陣。

translate(x,y) 定義 2D 平移轉換。

translate3d(x,y,z) 定義 3D 平移轉換。

translateX(x) 定義X 軸平移轉換

translateY(y) 定義Y 軸平移轉換

translateZ(z) 定義 Z 軸3D 平移轉換

scale(x[,y]) 定義 2D 縮放轉換。

scale3d(x,y,z) 定義 3D 縮放轉換。

scaleX(x) 通過設定 X 軸的值來定義縮放轉換。

scaleY(y) 通過設定 Y 軸的值來定義縮放轉換。

scaleZ(z) 通過設定 Z 軸的值來定義 3D 縮放轉換。

rotate(angle) 定義 2D 旋轉,在引數中規定角度。

rotate3d(x,y,z,angle) 定義 3D 旋轉。

rotateX(angle) 定義沿著 X 軸的 3D 旋轉。

rotateY(angle) 定義沿著 Y 軸的 3D 旋轉。

rotateZ(angle) 定義沿著 Z 軸的 3D 旋轉。

skew(x-angle,y-angle) 定義沿著 X 和 Y 軸的 2D 傾斜轉換。

skewX(angle) 定義沿著 X 軸的 2D 傾斜轉換。

skewY(angle) 定義沿著 Y 軸的 2D 傾斜轉換。

perspective(n) 為 3D 轉換元素定義透視檢視。

例如,transform: translate(50px,100px);表示元素從左邊移動50個畫素,並從頂部移動100畫素。

將例1中.container:hover .move-box的定義修改為:

.container:hover .move-box

{

transform: translate(250px,0);

}

.container:hover .move-box

{

transform: translateX(250px);

}

同樣可以實現如圖2所示的頁面效果。但transform屬性的設定更靈活。

例如,將例1中.container:hover .move-box的定義修改為:

.container:hover .move-box

{

transform: translate(250px,150px);

}

則可得到如圖4所示的動畫效果。此時,藍色小正方形在水平和垂直方向上都發生了平移。

圖4 藍色小正方形沿對角線平移

再如,將例1中.container:hover .move-box的定義修改為:

.container:hover .move-box

{

transform: rotate(45deg) translateX(200px);

}

則可得到如圖5所示的動畫效果。

圖5 藍色小正方形旋轉並平移

例2 圖片的平移、縮放和旋轉變換。

在頁面中放置一個類名為container的層作為效果展示容器,在該層中再定義一個9個子層,每個子層中放置一幅圖片,為圖片新增滑鼠懸停變換效果,當滑鼠懸停在某幅圖片上時,該圖片或平移、或縮放、或旋轉。編寫完整的HTML程式碼如下。

<!DOCTYPE html>
<html>
<head>
<title>圖片的平移、縮放和旋轉變換</title>
<style>
   *{
      margin: 0;
      padding: 0;
   }
   .container
   {
     border: 3px solid rgba(255, 0, 255, 0.9);
      width: 1000px;
      height: 600px;
      display: flex;
      margin-left: 200px;
      flex-direction: row;
      flex-wrap: wrap;
      justify-content: space-around;
      align-content: space-around;
   }
   .container>div
   {
      width: 300px;
      height: 150px;
      transition-duration: 2s;
   }
   .container>div>img
   {
      width: 100%;
      height: 100%;
   }
   .container>div:nth-child(1):hover
   {
       transform: translate(665px,200px);
   }
   .container>div:nth-child(2):hover
   {
       transform: rotateX(60deg);  
   }
   .container>div:nth-child(3):hover
   {
       transform: rotateY(60deg);
   }
   .container>div:nth-child(4):hover
   {
       transform: rotateX(360deg);
   }
   .container>div:nth-child(5):hover
   {
      transform: scale(2);
   }
   .container>div:nth-child(6):hover
   {
      transform: rotateY(360deg);
   }
   .container>div:nth-child(7):hover
   {
      transform: rotateZ(360deg); 
   }
   .container>div:nth-child(8):hover
   {
      transform: rotateZ(180deg);
   }
   .container>div:nth-child(9):hover
   {
      transform: skew(30deg);  
   }
</style>
</head>
<body>
<div class="container">
     <div><img src="mlh.jpg" alt=""/></div>
     <div><img src="mls.jpg" alt=""/></div>
     <div><img src="mltc.png" alt=""/></div>
     <div><img src="mlyws.png" alt=""/></div>
     <div><img src="hhl.jpg" alt=""/></div>
     <div><img src="mlcy.png" alt=""/></div>
     <div><img src="mlmgy.png" alt=""/></div>
     <div><img src="mljlg.png" alt=""/></div>
     <div><img src="mlqlz.png" alt=""/></div>
 </div>
</body>
</html>
View Code

在瀏覽器中開啟儲存上述HTML程式碼的html檔案,在瀏覽器中呈現出如圖6所示的變換效果(部分示例)。

圖6 圖片旋轉

transition的優點在於簡單易用,但是它有幾個很大的侷限。

(1)transition需要事件觸發,所以沒法在網頁載入時自動發生。例1和例2都是採用偽選擇器hover,在滑鼠懸停時產生動畫效果。

(2)transition是一次性的,不能重複發生,除非一再觸發。

(3)transition只能定義開始狀態和結束狀態,不能定義中間狀態,也就是說只有兩個狀態。例如,例1中的藍色小正方形只能沿一條指定的路線移動。若想讓藍色小正方形沿著上下左右邊界轉圈移動,transition屬性就沒法做到。

CSS Animation就是為了解決這些問題而提出的。

2.animation 屬性

animation 屬性是六個動畫屬性的簡寫屬性,這6個屬性是animation-name、animation-duration、animation-timing-function、animation-delay、animation-iteration-count和animation-direction。

(1)animation-name屬性。

animation-name 屬性為 @keyframes 動畫規定名稱。其格式為:

animation-name: keyframename|none;

其中,屬性值keyframename規定需要繫結到選擇器的keyframe的名稱。屬性值none規定無動畫效果(可用於覆蓋來自級聯的動畫)。

(2)animation-duration屬性。

animation-duration 屬性定義動畫完成一個週期所需要的時間,以秒或毫秒計。其格式為: animation-duration: time;

(3)animation-timing-function屬性。

animation-timing-function屬性規定動畫的速度曲線。速度曲線用於,使變化更為平滑。其格式為:

animation-timing-function: linear|ease|ease-in|ease-out|ease-in-out|cubic-bezier(n,n,n,n);

各屬性值的功能描述如下:

linear 動畫從頭到尾的速度是相同的。

ease 預設。動畫以低速開始,然後加快,在結束前變慢。

ease-in 動畫以低速開始。

ease-out 動畫以低速結束。

ease-in-out 動畫以低速開始和結束。

cubic-bezier(n,n,n,n) 在 cubic-bezier 函式中定義自己的值。可能的值是從 0 到 1 的數值。

(4)animation-delay屬性。

animation-delay 屬性定義動畫什麼時候開始。其格式為:

animation-delay: time;

屬性值time單位可以是秒(s)或毫秒(ms)。並且time允許負值,-2s 使動畫馬上開始,但跳過 2 秒進入動畫。

(5)animation-iteration-count屬性。

animation-iteration-count 屬性定義動畫的播放次數。其格式為:

animation-iteration-count: n|infinite;

其中,屬性值n定義動畫播放次數的數值;屬性值infinite規定動畫應該無限次播放。

(6)animation-direction屬性。

animation-direction屬性規定是否應該輪流反向播放動畫。其格式為:

animation-direction: normal|reverse|alternate|alternate-reverse;

其中,屬性值normal表示以正常的方式播放動畫;reverse 以相反方向播放動畫;alternate 播放動畫時,每奇數時間(1,3,5…)正常播放,每偶數時間(2,4,6…)反方向播放; alternate-reverse播放動畫時,每奇數時間(1,3,5…)反方向播放,每偶數時間(2,4,6…)正常播放。

例3 沿著容器邊框轉圈移動的藍色小正方形。

修改例1中的效果,使得藍色小正方形可以沿著上邊框、右邊框、下邊框和左邊框迴圈轉圈。編寫HTML檔案如下。

<!DOCTYPE html>
<html>
<head>
<title>沿邊框四周移動的小正方形</title>
<style>
.container
{
     width: 300px;
     height: 200px;
     border: 4px solid rgba(255, 0, 0, 0.9);
}
.move-box
{
     left:0;
     top:0;
     width: 50px;
     height: 50px;
     position: relative;
     background: rgb(0,0,255);
     animation:myfirst 5s infinite;
}
@keyframes myfirst
{
    0%    { left:0px; top:0px;}
25%   { left:250px; top:0px;}
50%   { left:250px; top:150px;}
75%   { left:0px; top:150px; }
100%  { left:0px; top:0px;}
}
</style>
</head>
<body>
<div  class="container">
  <div class="move-box">
  </div>
</div>
</body>
</html>
View Code

在瀏覽器中開啟儲存上述HTML程式碼的html檔案,在瀏覽器中呈現出如圖7所示的動畫效果。

圖7 沿四周迴圈轉圈的小正方形

如在上面CSS定義的animation:myfirst 5s infinite;語句後,再加上一條語句animation-direction:alternate; ,則得到如圖8所示的動畫效果,與圖7的不同之處在於,偶數運動週期時,小正方形的移動方向沿著左邊框-->下邊框-->右邊框-->上邊框

圖8 沿四周迴圈轉圈的小正方形

需要說明的是:Internet Explorer 10、Firefox 以及 Opera 等支援 animation 屬性,Safari 和 Chrome 支援替代的 -webkit-animation 屬性,而Internet Explorer 9 以及更早的版本不支援 animation 屬性。因此,從瀏覽器相容性的角度出發,在例3的HTML檔案的CSS定義中可加上如下定義:

@-webkit-keyframes myfirst

{

0% { left:0px; top:0px;}

25% { left:250px; top:0px;}

50% { left:250px; top:150px;}

75% { left:0px; top:150px; }

100% { left:0px; top:0px;}

}

例4 圖片的縮放、旋轉和傾斜動畫。

在頁面中放置一個類名為container的層作為效果展示容器,在該層中再定義一個4個子層,每個子層中放置一幅圖片,為每幅圖片新增動畫效果,第1幅圖片縮小後放大,第2幅圖片繞X軸翻轉,第3幅圖片沿Z軸旋轉,第4幅圖片傾斜。編寫完整的HTML程式碼如下。

<!DOCTYPE html>
<html>
<head>
<title>圖片的縮放、旋轉和傾斜變換</title>
<style>
   *{
      margin: 0;
      padding: 0;
   }
   .container
   {
      border: 3px solid rgba(255, 0, 255, 0.9);
      width: 850px;
      height: 550px;
      display: flex;
      margin: 0 auto;
      flex-direction: row;
      flex-wrap: wrap;
      justify-content: space-around;
      align-content: space-around;
   }
   .container>div
   {
      width: 400px;
      height:250px;
   }
   .container>div>img
   {
      width: 100%;
      height: 100%;
   }
   .container>div:nth-child(1)
   {
      animation:myAnim1 3s infinite;
   }
   @keyframes myAnim1
   {
      0%    { transform: none;}
      50%   { transform: scale(0);}
      100%  { transform: scale(1);}
   }
   .container>div:nth-child(2)
   {
      animation:myAnim2 3s infinite;
   }
   @keyframes myAnim2
   {
      0%    { transform: none;}
      100%  { transform: rotateX(360deg);}
   }
   .container>div:nth-child(3)
   {
      animation:myAnim3 3s infinite;
   }
   @keyframes myAnim3
   {
      from    { transform: none;}
      to      { transform: rotateZ(360deg);}
   }
   .container>div:nth-child(4)
   {
      animation:myAnim4 3s infinite;
   }
   @keyframes myAnim4
   {
      0%    { transform: none;}
      33%  { transform: skew(15deg,15deg);}
      67%   { transform: skew(-15deg,-15deg);}
      100%  { transform: skew(0deg,0deg);}
   }
</style>
</head>
<body>
<div class="container">
     <div><img src="mlh.jpg" alt=""/></div>
     <div><img src="hhl.jpg" alt=""/></div>
     <div><img src="mlcy.png" alt=""/></div>
     <div><img src="mltc.png" alt=""/></div>
</div>
</body>
</html>
View Code

在瀏覽器中開啟儲存上述HTML程式碼的html檔案,在瀏覽器中呈現出如圖9所示的動畫效果。

圖9 圖片的縮放、旋轉和傾斜動畫

例5 旋轉的文字。

在頁面中放置一個類名為container的層作為效果展示容器,在該層中再定義一個3個子層,每個子層中放置一個漢字,為每個漢字所在的層新增動畫效果,第1個漢字水平翻轉,第2個漢字繞中心旋轉,第3個漢字垂直翻轉。編寫完整的HTML程式碼如下。

<!DOCTYPE html>
<html>
<head>
<title>歡樂頌</title>
<style>
.container
{
   margin: 0 auto;
   width: 650px;
   height: 250px;
   display: flex;
   flex-direction: row;
   flex-wrap: wrap;
   border: 4px solid rgba(255, 0, 0, 0.9);
} 
.container>div
{
   width:200px;
   height:200px;
   margin:20px auto;
   text-align: center;
   font:800 100px/200px "隸書";
   border-radius: 50%;
   transform-origin:center 50%;
}
.container>div:nth-child(1)
{
   background:#f00;
   animation: anim1 2s infinite linear;
}
@keyframes anim1
{
    from { transform: rotate(0);}
    to   { transform: rotateX(360deg);}
}
.container>div:nth-child(2)
{
   background:#0f0;
   animation: anim2 2s infinite linear;
}
@keyframes anim2
{
    from { transform: rotate(0);}
    to   { transform: rotate(360deg);}
}
.container>div:nth-child(3)
{
   background:#00f;
   animation: anim3 2s infinite linear;
}
@keyframes anim3
{
    from { transform: rotate(0);}
    to   { transform: rotateY(360deg);}
}
</style>
</head>
<body>
<div  class="container">
<div></div><div></div><div></div>
</div>    
</body>
</html>
View Code

在瀏覽器中開啟儲存上述HTML程式碼的html檔案,在瀏覽器中呈現出如圖10所示的動畫效果。

圖10 漢字的旋轉

例6 旋轉的風車。

預先準備好一張風車的圖片,在頁面中放置一個類名為container的層作為效果展示容器,將風車圖片作為該層的背景圖片。滑鼠懸停在層上時,風車旋轉,滑鼠移離,風車停止旋轉。編寫完整的HTML程式碼如下。

<!DOCTYPE html>
<html>
<head>
<title>旋轉的風車</title>
<style>
.container
{
   margin: 0 auto;
   background-image: url(a1.png);
   width: 300px;
   height: 300px;
   background-position: center center;
   background-repeat: no-repeat;
   background-size: cover;
   border-radius: 50%;
   vertical-align: middle;
   border: 4px solid rgba(255, 0, 0, 0.9);
} 
.container:hover {
   animation: anim 2s linear infinite;
}
@keyframes anim 
{
   0%   {  transform: rotate(0deg);    }
   100% {  transform: rotate(360deg);  }
}
</style>
</head>
<body>
<div  class="container"></div>    
</body>
</html>
View Code

在瀏覽器中開啟儲存上述HTML程式碼的html檔案,在瀏覽器中呈現出如圖11所示的動畫效果。

圖11 旋轉的風車

例7 方和圓。

實現方形變換為圓形,編寫HTML程式碼如下。

<!DOCTYPE html>
<html>
<head>
<title>方和圓</title>
<style>
.container
{
   margin: 0 auto;
   width: 350px;
   height: 250px;
   border: 4px solid rgba(255, 0, 0, 0.9);
} 
.container>div
{
   width:100px;
   height:100px;
   position: relative;
   left:0;
   top:75px;
   animation: anim1 4s infinite;      
}
@keyframes anim1
{
    from 
    {    
        background:#f00;
        transform:translate(0,0);
    }
    to   
    { 
        background:#00f;
        transform:translate(250px,0);
        border-radius: 50%;
    }
}
</style>
</head>
<body>
<div  class="container">
<div></div>
</div>    
</body>
</html>
View Code

在瀏覽器中開啟儲存上述HTML程式碼的html檔案,在瀏覽器中呈現出如圖12所示的動畫效果。

圖12 方和圓的變換