CSS3提供了豐富的動畫類屬性,使我們可以不通過flash甚至JavaScript,就能實現很多動態的效果。它們主要分為三大類:transform(變換),transition(過渡),animation(動畫)。其中transform又分為2D變換和3D變換,它賦予了我們不通過專業設計軟件制作平面或者立體圖形的能力。
一 過渡
通過給元素設置transition屬性設置它的過渡效果。過渡實際定義的是元素從一種狀態變成另一種狀態的過程,比如寬度從100px變成300px,背景顏色從red變成orange等等。
1 div{
2 width:200px;
3 height:200px;
4 background-color:red;
5 transition-property:width,background-color;
6 /*該屬性指定需要變換的元素屬性,不同屬性用逗號隔開*/
7 transition-duration:1s;
8 /*該屬性指定整個過程花費的時間,如需單獨為每個變化的屬性設置時間,請使用逗號隔開*/
9 transition-timing-function:ease;
10 /*該屬性設置變化的速度曲線,默認值即是ease,表示慢-快-慢,還有幾個其他的取值:linear,勻速;ease-in,慢-快,ease-out,快-慢,ease-in-out,慢-快-慢,肉眼效果和ease相似*/
11 transition-delay:1s;
12 /*延遲時間*/
13 }
元素的屬性設置好以后,需要某些操作觸發了指定屬性的變化才能看到效果,比如:hover,或者JS事件。
另外,transition實際是一個復合屬性,多個屬性過渡可以簡寫:
1 div{
2 width:200px;
3 height:200px;
4 transition:width 2s 1s,background-color 2s;
5 /*transition-property和transition-duration是必須的,另外兩個是可選的*/
6 }
7 div:hover{
8 width:400px 9 }
當有多個屬性需要設置過渡,並且持續事件,速度曲線,延遲時間均相同時,你可以如下簡寫:
1 div{
2 /*some code*/
3 transition:all 2s;
4 /*所有發生變化的屬性都設置過渡效果*/
5 }
二 動畫
動畫其實和過渡一樣,都是用來給元素設置動態效果的,不同的是,過渡需要人為的觸發才能被執行,而動畫不需要人為觸發。
在給元素設置動畫之前,我們首先應該創建一個動畫效果,即開始是什么狀態,結束是什么狀態。
1 @keyframes sport{/*通過@keyframs 定義一個動畫,sport是動畫的名稱,可以自定義*/
2 from{ 3 width:200px;
4 }
5 to{
6 width:400px;
7 }
8 /*除了使用from...to的方式,你還可以使用百分比創建更加豐富的動畫過程,0%表示開始時,100%表示結束時*/
9 }
創建好動畫之后,你就可以為元素設置諸如動畫持續時長,速度曲線,重復次數等屬性了。
1 div{
2 animation-name:sport;
3 /*規定元素需要執行的動畫名稱,即使用@keyframs創建的那個*/
4 animation-duration:5s;
5 /*規定動畫完成一個周期所花費的秒或毫秒*/
6 animation-timing-function:ease;
7 /*規定動畫的速度曲線,可選值同過渡*/
8 animation-delay:3s;
9 /*規定動畫延遲時間*/
10 animation-iteration-count:5;
11 /*規定動畫被播放的次數,infinite表示一直循環播放*/
12 animation-direction:alternate;
13 /*規定動畫是否在下一周期逆向地播放,normal是默認取值,表示不逆向播放,逆向播放一次也會在animation-iteration-count屬性值中減1*/
14 animation-play-state:paused;
15 /*規定動畫是否正在運行或暫停,默認值是running,表示正在運行*/
16 animation-fill-mode:forwards;
17 /*規定動畫結束后元素的狀態,forwards,保持動畫停止時的狀態,backwards,回到開始時的狀態,none,保持默認。一般沒有指定該屬性時,動畫結束后會回到開始時的狀態。不同瀏覽器可能有不同表現*/
18 }
animation 也是一個復合屬性,可以如下簡寫:
1 div{ 2 animation:sport 5s ease 2s infinite alternate forwords; 3 } 4 /* animation-play-state 一般通過偽類或JS來動態的控制動畫的暫停或繼續 */
三 2D變換
通過給元素設置 transform 屬性,可以對元素進行2D變換。很多地方把 transform 翻譯成轉換,該單詞在英語中的含義是使改變,使變形。我更傾向於把它翻譯成變換,通過CSS變換,我們可以對元素進行移動、縮放、轉動、拉伸等操作。
1,translate(x,y)
1 div{
2 transform:translate(50px,100px);
3 }
4 /*div在水平方向基於原位置移動50px,垂直方向移動100px*/
translate方法接收兩個參數,分別表示在水平和垂直正方向上的偏移量,可以接收負值,表示向反方向偏移。
2,rotate(deg)
1 div{
2 transform:rotate(30deg);
3 }
4 /*順時針方向旋轉元素30度*/
rotate方法接收一個參數,表示元素旋轉的角度,可以接收負值,表示逆時針方向旋轉。rotate方法實際是通過修改元素的坐標系來達到旋轉元素的目的,比如:
1 div{
2 transform:rotate(45deg) translate(50px,0);
3 /*多屬性復合形式寫法*/
4 }
5 /*元素先旋轉45度,然后向瀏覽器x軸正方向偏下45度的方向移動50px*/
默認情況下,元素都是以自己的中心點為圓心旋轉,我們可以通過transform-origin屬性修改該參考點。
1 div{
2 width:200px;
3 height:200px;
4 transform:rotate(30deg);
5 transform-origin:0px 0px;/*以左上角為圓點旋轉*/
6 /*取值200px 0px即以右上角為圓點旋轉。改屬性取值也可以是百分比或關鍵字。top,botton,left,right,center*/
7 }
3,scale(x,y)
1 div{
2 transform:scale(2,3);
3 }
4 /*元素寬度放大2倍,高度放大3倍*/
scale方法接收兩個參數,分別表示元素寬高需要縮放的比例,如果參數介於0到1之間則表示縮小,如果小於0,實際效果相當於翻轉元素,感興趣的朋友可以自行測試,觀察效果。
4,skew(x,y)
1 div{
2 transform:skew(30deg,30deg);
3 }
4 /*元素在水平和垂直方向均傾斜30度*/
skew方法接收兩個參數,分別表示X軸和Y軸傾斜的角度,如果第二個參數為空,則默認為0,參數為負表示向相反方向傾斜。
四 3D變換
要想使元素以3D效果呈現,你需要給元素的父元素添加transform-style屬性。
1 .father{
2 transform-style:preserve-3d;
3 }
4 .son{
5 /*some code*/
6 }
transform-style屬性的默認值是flat,即平面的意思。通過設置其值為preserve-3d即可讓子元素以3D模式呈現。
事實上,我們是通過配合使用rotate方法,最終實現3D立體效果的。
我們知道,在2D空間,坐標軸只有x和y兩根軸,而在3D空間,一共有x,y,z三根軸。我們上面講解的rotate方法實際上都是圍繞z軸在旋轉,這也是該方法的默認方式。另外,其實我們還可以通過rotateX(),rotateY(),改變元素默認的旋轉軸向。改變旋轉軸向配合perspective屬性使用效果更佳。
1 .father{ 2 perspective:500px; 3 /*perspective屬性取值是一般是一個像素值,設置后可以實現旋轉后元素近大遠小的效果*/ 4 } 5 .son{ 6 width:200px; 7 height:200px; 8 transform:rotateX(45deg); 9 }
10 /*注意,perspective屬性需要設置在旋轉元素的祖先元素上,通常我們把它設置在其父元素上。*/
下面是兩個3D立方體的示例代碼:
HTML部分:
1 <div class="D3">
2 <ul>
3 <li>1</li>
4 <li>2</li>
5 <li>3</li>
6 <li>4</li>
7 <li>5</li>
8 <li>6</li>
9 </ul>
10 <ul>
11 <li>1</li>
12 <li>2</li>
13 <li>3</li>
14 <li>4</li>
15 <li>5</li>
16 <li>6</li>
17 </ul>
18 </div>
CSS部分:
1 body{
2 background-color: #ccc;
3 perspective: 800px;
4 }
5 .D3{
6 width:550px;
7 height: 200px;
8 margin:100px auto;
9 }
10 @keyframes sport{
11 from{ 12 transform: rotateX(0deg) rotateY(0deg);
13 }
14 to{
15 transform: rotateX(360deg) rotateY(360deg);
16 }
17 } 18 .D3 ul{
19 width: 200px;
20 height: 200px;
21 position: relative;
22 transform-style: preserve-3d;
23 transform: rotateX(0deg) rotateY(0deg);
24 animation: sport 10s linear infinite alternate;
25 display: inline-block;
26 margin-left:50px;
27 }
28 .D3 ul li{
29 list-style: none;
30 width:200px;
31 height: 200px;
32 position: absolute;
33 opacity: 0.3;
34 font-size: 100px;
35 line-height: 200px;
36 text-align: center;
37 }
38 .D3 ul li:nth-child(1){
39 background-color: red;
40 transform:translateZ(100px);
41 }
42 .D3 ul li:nth-child(2){
43 background-color: blue;
44 transform: rotateX(90deg) translateZ(100px);
45 }
46 .D3 ul li:nth-child(3){
47 background-color: yellow;
48 transform: rotateX(180deg) translateZ(100px);
49 }
50 .D3 ul li:nth-child(4){
51 background-color: pink;
52 transform: rotateX(270deg) translateZ(100px);
53 }
54 .D3 ul li:nth-child(5){
55 background-color: purple;
56 transform: rotateY(90deg) translateZ(-100px);
57 }
58 .D3 ul li:nth-child(6){
59 background-color: green;
60 transform: rotateY(90deg) translateZ(100px);
61 }
62 /*還記得嗎?rotate方法是通過改變坐標系來達到旋轉的目的哦!*/
五 transform對其他元素的影響
1,提高顯示優先級
我們知道,在標准文檔流中,如果使用負的margin值可以使一個元素覆蓋在另一個元素上,正常情況下是寫在后面的元素覆蓋前面的。但是設置了transform屬性的元素會覆蓋其他元素。
1 .top{
2 width: 100px;
3 height: 100px;
4 background-color: red;
5 transform: rotate(0deg);
6 }
7 .bottom{
8 width: 100px;
9 height: 100px;
10 background-color: blue;
11 margin-top:-50px;
12 }
13 /*紅色的會覆蓋藍色的div 50px*/
2,改變fixed定位的相對對象
通常情況下,使用了position:fixed;屬性的元素都會相對瀏覽器窗口定位,不受滾動條的影響。但是當我們給其父元素設置了transform屬性后,這一狀況被改變了。
1 .father{
2 width: 500px;
3 height: 500px;
4 margin-left: 100px;
5 margin-top: 100px;
6 border: 1px solid #000;
7 transform: rotate(0deg);
8 }
9 .son{
10 position: fixed;
11 top: 50px;
12 left:50px;
13 width: 100px;
14 height: 100px;
15 background-color: red;
16 }
17 /*.son不再以瀏覽器窗口作為參考點,而是以其父元素.father作為按參考點了*/
3,改變absolute定位元素的寬度
以前,如果一個元素設置了絕對定位,並且寬度設置為100%,那么該元素的實際寬度是第一個有定位屬性的祖先元素的寬度,沒有則是body的寬度。現在,如果第一個有定位屬性的祖先元素和絕對定位元素之間,有一個設置了transform屬性的元素,那么絕對定位元素的寬度繼承鏈將在該transform祖先元素處被截斷,最終絕對定位的元素寬度將繼承自transform元素。
1 .grand{
2 width: 500px;
3 height: 500px;
4 border: 1px solid #000;
5 position: absolute;
6 }
7 .father{
8 width: 100px;
9 height: 100px;
10 background-color: red;
11 transform:rotate(0deg);
12 }
13 .son{
14 width: 100%;
15 height: 200px;
16 position: absolute;
17 background-color: yellow;
18 }
19 /*.son的寬度不是500px,而變成了100px*/
寫在最后,transform是CSS3才引入的屬性,不同瀏覽器對它的實現也可能有差異,上面介紹的內容並不能保證在所有瀏覽器上均有相同的表現,具體情況請大家自行測試(我僅在Chrome 76測試)。