一、CSS3變形簡介
CSS3變形是一些效果的集合,比如平移、旋轉、縮放和傾斜效果,每個效果都稱為變形函數(Transform Function)。
CSS變形允許動態的控制元素,可以在屏幕周圍移動,縮小,旋轉,或結合所有這些產生復雜的動畫效果。
二、變形屬性
1、transform屬性
transform屬性讓元素在一個坐標系統中變形,包含一系列變形函數。
語法:transform:none|<transform-function>
可用于內聯元素和塊元素,默認值為none,表示元素不進行變形;另一個屬性值是<transform-function>,表示一個或多個變形函數,以空格分開。
2、transform-function函數
所有的2D變形函數也包含于3D變形規范中。
2D常用的transform-function的功能
函數 | 功能描述 |
---|---|
translate() | 移動元素,可以根據X軸和Y軸坐標重新定位元素位置,兩個擴展函數translateX()和translateY() |
scale() | 縮小或放大元素,兩個擴展函數scaleX()和scaleY() |
rotate() | 旋轉元素 |
skew() | 讓元素傾斜,兩個擴展函數skewX()和skewY() |
matrix() | 定義矩陣變形,基于X軸和Y軸坐標重新定位元素位置 |
3D常用的transform-function功能
函數 | 功能描述 |
---|---|
translate3d() | 移動元素,用來指定一個3D變形移動位移量 |
scale3d() | 縮放一個元素 |
rotate3d() | 指定元素具有一個三維旋轉的角度 |
perspective() | 指定一個透視投影矩陣 |
matrix3d() | 定義矩陣變形 |
3、transform-origin屬性
transform-origin屬性用來指定元素的中心點位置。變形的原點在元素的中心點,或者是元素X軸和Y軸的50%處。
transform-origin屬性值可以是百分比,em、px等具體的值,也可以是top、right、bottom、left和center的關鍵詞。
2D變形中的transform-origin屬性可以是一個參數值,也可以是兩個參數值。如果是兩個參數值,第一個設置水平方向X軸的位置,第二個設置垂直方向Y軸的位置。
3D變形中的transform-origin屬性包括了Z軸。
3D變形中transform-origin屬性
屬性值 | 功能描述 |
---|---|
x-offset | 設置transform-origin水平方向X軸的偏移量,可以是正值(從中心點沿水平方向X軸向右偏移量),也可以是負值(從中心點沿水平方向X軸向左偏移量) |
offset-keyword | 是top、right、bottom、left或center中的一個關鍵詞,用來設置transform-origin偏移量 |
y-offset | 設置transform-origin屬性在垂直方向Y軸的偏移量,可以是正值(從中心點沿垂直方向Y軸向下的偏移量),也可以是負值(從中心點沿垂直方向向上的偏移量) |
x-offset-keyword | 是left、right或center中的一個關鍵詞,設置transform-origin屬性值在水平X軸的偏移量 |
y-offset-keyword | 是top、bottom和center中的一個關鍵詞,設置transform-origin屬性值在垂直Y軸的偏移量 |
z-offset | 設置3D變形中transform-origin遠離用戶眼睛視點的距離,默認值z=0,取值可以是<length> |
4、transform-style屬性
transform-style屬性是3D空間一個重要屬性,指定嵌套元素如何在3D空間中呈現,主要有兩個屬性:flat和preserve-3d
語法:transform-style:flat|preserve-3d
- flat:默認值,表示所有子元素在2D平面呈現
- preserve-3d:所有子元素在3D空間呈現
5、perspective屬性
perspective屬性會設置查看者的位置,并將可視內容映射到一個視錐上,繼而投到一個2D視平面上。
語法:perspective:none|<length>
參數說明:
- none:默認值,表示無限的角度來看3D物體,但看上去是平的。
- <length>:接受一個長度單位大于0的值,不能為百分比值。值越大,角度出現的越遠,從而創建一個相當低的強度和非常小的3D空間變化;反之,值越小,角度出現的越近,從而創建一個高強度的角度和大型的3D變化。
示例圖:
示例代碼:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>CSS3變形</title>
<style>
.wrapper {
width: 50%;
float: left;
}
.cube {
font-size: 4em;
width: 2em;
margin: 1.5em auto;
transform-style: preserve-3d;
transform: rotateX(-40deg) rotateY(32deg);
}
.side {
position: absolute;
width: 2em;
height: 2em;
background: rgba(255, 99, 71, 0.6);
border: solid 1px rgba(0, 0, 0, 0.5);
color: white;
text-align: center;
line-height: 2em;
}
.front {
transform: translateZ(1em);
}
.top {
transform: rotateX(90deg) translateZ(1em);
}
.right {
transform: rotateY(90deg) translateZ(1em);
}
.bottom {
transform: rotateX(-90deg) translateZ(1em);
}
.left {
transform: rotateY(90deg) translateZ(1em);
}
.back {
transform: rotateY(-180deg) translateZ(1em);
}
.w1 {
perspective: 100px;
}
.w2 {
perspective: 1000px;
}
</style>
</head>
<body>
<div class="wrapper w2">
<div class="cube">
<div class="side front">1</div>
<div class="side back">6</div>
<div class="side right">4</div>
<div class="side left">3</div>
<div class="side top">5</div>
<div class="side bottom">2</div>
</div>
</div>
<div class="wrapper w1">
<div class="cube">
<div class="side front">1</div>
<div class="side back">6</div>
<div class="side right">4</div>
<div class="side left">3</div>
<div class="side top">5</div>
<div class="side bottom">2</div>
</div>
</div>
</body>
</html>
perspective的簡單結論:
- perspective取值為none或不設置,沒有3D空間。
- perspective取值越小,3D效果就越明顯,也就眼睛越靠近真3D;
- perspective的值無窮大,或值為0時與取值為none效果一樣
perspective()函數與perspective屬性:
perspective函數也可以激活3D空間,不同之處:perspective用在舞臺元素上(變形元素的父元素);perspective()函數用在當前變形元素上。
6、perspective-origin屬性
perspective-origin屬性主要用來決定perspective屬性的源點角度,實際上設置了X軸和Y軸位置,在該位置觀看者好像在觀看該元素的子元素。
語法:perspective-origin:<percentage>|<length>|left|center|right|top|bottom
該屬性默認值為50% 50%
(就是center),可以設置為一個值,也可以設置為兩個長度值。
第一個長度值指定相對于元素的包含框的X軸上的位置,可以是長度值、百分比或以下關鍵詞之一:
- left:在包含框的X軸方向長度的0%
- center:中間點
- right:長度的100%
第二個長度值指定相對于元素的包含框的Y軸上的位置,可以是長度值、百分比或以下關鍵詞之一:
- left:在包含框的X軸方向長度的0%
- center:中間點
- right:長度的100%
注意:為了指轉換子元素變形的深度,perspective-origin屬性必須定義在父元素上。perspective-origin屬性需要與perspective屬性結合起來使用,以便將視點移至元素的中心以外的位置。
示例圖:
示例代碼:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>CSS3變形</title>
<style>
.wrapper {
width: 30%;
display: inline-block;
padding-bottom: 1em;
}
.wrapper h1 {
text-align: center;
font-size: 1.5em;
}
.cube {
font-size: 2em;
width: 2em;
height: 2em;
margin: .5em auto;
transform-style: preserve-3d;
perspective: 250px;
}
.w1 .cube {
perspective-origin: top left;
}
.w2 .cube {
perspective-origin: top;
}
.w3 .cube {
perspective-origin: top right;
}
.w4 .cube {
perspective-origin: left;
}
.w5 .cube {
perspective-origin: center;
}
.w6 .cube {
perspective-origin: right;
}
.w7 .cube {
perspective-origin: bottom left;
}
.w8 .cube {
perspective-origin: bottom;
}
.w9 .cube {
perspective-origin: bottom right;
}
.side {
position: absolute;
width: 2em;
height: 2em;
background: rgba(255, 99, 71, 0.6);
border: solid 1px rgba(0, 0, 0, 0.5);
color: white;
text-align: center;
line-height: 2em;
}
.front {
transform: translateZ(1em);
}
.top {
transform: rotateX(90deg) translateZ(1em);
}
.right {
transform: rotateY(90deg) translateZ(1em);
}
.left {
transform: rotateY(-90deg) translateZ(1em);
}
.bottom {
transform: rotateX(-90deg) translateZ(1em);
}
.back {
transform: rotateY(-180deg) translateZ(1em);
}
</style>
</head>
<body>
<div class="wrapper w1">
<h1><code>top left</code></h1>
<div class="cube">
<div class="side front">1</div>
<div class="side back">6</div>
<div class="side right">4</div>
<div class="side left">3</div>
<div class="side top">5</div>
<div class="side bottom">2</div>
</div>
</div>
<div class="wrapper w2">
<h1><code>top</code></h1>
<div class="cube">
<div class="side front">1</div>
<div class="side back">6</div>
<div class="side right">4</div>
<div class="side left">3</div>
<div class="side top">5</div>
<div class="side bottom">2</div>
</div>
</div>
<div class="wrapper w3">
<h1><code>top right</code></h1>
<div class="cube">
<div class="side front">1</div>
<div class="side back">6</div>
<div class="side right">4</div>
<div class="side left">3</div>
<div class="side top">5</div>
<div class="side bottom">2</div>
</div>
</div>
<div class="wrapper w4">
<h1><code>left</code></h1>
<div class="cube">
<div class="side front">1</div>
<div class="side back">6</div>
<div class="side right">4</div>
<div class="side left">3</div>
<div class="side top">5</div>
<div class="side bottom">2</div>
</div>
</div>
<div class="wrapper w5">
<h1><code>center</code></h1>
<div class="cube">
<div class="side front">1</div>
<div class="side back">6</div>
<div class="side right">4</div>
<div class="side left">3</div>
<div class="side top">5</div>
<div class="side bottom">2</div>
</div>
</div>
<div class="wrapper w6">
<h1><code>right</code></h1>
<div class="cube">
<div class="side front">1</div>
<div class="side back">6</div>
<div class="side right">4</div>
<div class="side left">3</div>
<div class="side top">5</div>
<div class="side bottom">2</div>
</div>
</div>
<div class="wrapper w7">
<h1><code>bottom left</code></h1>
<div class="cube">
<div class="side front">1</div>
<div class="side back">6</div>
<div class="side right">4</div>
<div class="side left">3</div>
<div class="side top">5</div>
<div class="side bottom">2</div>
</div>
</div>
<div class="wrapper w8">
<h1><code>bottom</code></h1>
<div class="cube">
<div class="side front">1</div>
<div class="side back">6</div>
<div class="side right">4</div>
<div class="side left">3</div>
<div class="side top">5</div>
<div class="side bottom">2</div>
</div>
</div>
<div class="wrapper w9">
<h1><code>bottom right</code></h1>
<div class="cube">
<div class="side front">1</div>
<div class="side back">6</div>
<div class="side right">4</div>
<div class="side left">3</div>
<div class="side top">5</div>
<div class="side bottom">2</div>
</div>
</div>
</body>
</html>
7、backface-visibility屬性
backface-visibility決定元素旋轉背面是否可見。對于未旋轉的元素,該元素的正面面向觀看者。當其Y軸旋轉約180度時會導致元素的背面面對觀眾。
語法:backface-visibility:visible|hidden
- visible:默認值,反面可見
- hidden:反面不可見
三、CSS3 2D 變形
1、2D位移
在這里 translate是一種方法,將元素向指定的方向移動。可以理解為,使用translate()函數可以把元素從原來的位置移動,而不影響在X、Y軸上任何組件。
語法:translate(tx)
或translate(tx,ty)
translate()函數可以取一個值,也可以取兩個值。
參數說明:
- tx:代表X軸(橫坐標)移動的向量長度,為正值時,元素向X軸右方向移動;為負值時,元素向X軸左方向移動。
- ty:代表Y軸(縱坐標)移動的向量長度,為正值時,元素向Y軸下方向移動;為負值時,元素向Y軸上方向移動。如果ty沒有顯示設置時,相當于ty=0.
結合起來,translate()函數移動元素主要有以下三種情況:
- 水平移動:向右移動translate(tx,0),向左移動translate(-tx,0)。
- 垂直移動:向上移動translate(0,-ty),向下移動translate(0,ty)。
- 對角移動:右下角移動translate(tx,ty)、右上角移動translate(tx,-ty)、左上角移動translate(-tx,-ty),左下角translate(-tx,ty)。
單獨一個方向移動對象的方法:
- translateX:水平方向移動一個對象。對象只向X軸進行移動。為正值,對象向右移動;為負值,對象向左移動。
- translateY:垂直方向移動一個對象。對象只向Y軸進行移動。為正值,對象向下移動;為負值,對象向上移動。
2、2D縮放
縮放函數scale()讓元素根據中心原點對對象進行縮放,默認值為1。0.01~0.99之間的值使一個元素縮小;大于等于1.01的值使元素顯得更大。
語法:scale(sx)
或scale(sx,sy)
可以接受一個值,也可以接受兩個值,只有一個值時,第二個值默認與第一個值相等。
- sx:指定橫向坐標(X軸)方向的縮放量。如果值為0.01~0.99之間的值使對象在X軸方向縮小;如果值為大于等于1.01的值使對象在X軸方向放大。
- sy:指定縱坐標(Y軸)方向的縮放量。如果值為0.01~0.99之間的值使對象在Y軸方向縮小;如果值為大于等于1.01的值使對象在Y軸方向放大。
單獨一個方向縮放對象的方法:
- scaleX:相當于scale(sx,1),表示元素只在X軸縮放元素,默認值是1;
- scaleY:相當于scale(1,sy),表示元素只在Y軸縮放元素,默認值是1;
在scale()函數中除了可以取正值,還可以取負值,只不過取負值時,會先讓元素反轉再進行縮放。
scale()函數對元素進行縮放時,都是以元素的中心為基點,但可以通過transform-origin改變元素的基點。
3、2D旋轉
rotate()函數通過指定角度對元素對象的原點指定一個2D旋轉。如果為正值,元素相對原點中心順時針旋轉;如果為負值,元素相對原點中心逆時針旋轉。
語法:rotate(a)
,只接受一個值,代表旋轉的角度值。
示例圖:
示例代碼:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>CSS3變形</title>
<style>
.rot{
width:5em;
height: 5em;
border:solid rgba(0,0,0,0.5) 1px;
background-color:orange;
margin:5em 2em;
display: inline-block;
}
.rot45deg{
transform:rotate(45deg);
}
.rot-45deg{
transform:rotate(-45deg);
}
</style>
</head>
<body>
<div class="rot rot45deg">順時針旋轉45度</div>
<div class="rot">原圖</div>
<div class="rot rot-45deg">逆時針旋轉45度</div>
</body>
</html>
4、2D傾斜
skew()函數可以將一個對象以其中心位置圍繞著X軸和Y軸按照一定的角度傾斜。與rotate()只會旋轉,不會改變元素的形狀,skew函數會改變元素的形狀。
語法:skew(ax)
或skew(ax,ay)
如果為設置值,默認為0。
- ax:指定元素水平方向(X軸)傾斜的角度;
- ay:指定元素垂直方向(Y軸)傾斜的角度;
單獨一個方向傾斜對象的方法:
- skewX():相當于skew(ax,0)和skew(ax)。skewX()使元素以其中心為基點,在水平方向傾斜;
- skewY():相當于skew(0,ay)。skewY()使元素以其中心為基點,在垂直方向傾斜;
默認值情況下,skew()函數以元素的原中心點對元素進行傾斜變形,但可以通過transform-origin屬性重新設置元素基點對元素進行傾斜變形。
5、2D矩陣
變形中的矩陣函數matrix()不常用。在CSS3中的變形都可以使用matrix()函數代替。
四、CSS3 3D變形
使用三維變形,可以改變元素在Z軸位置。三維變換使用基于二維變換的相同屬性。
3D變換主要包括以下幾種功能函數:
- 3D位移:包括translateZ()和translate3d()兩個功能函數;
- 3D旋轉:包括rotateX()、rotateY()、rotateZ()和rotate3d()四個功能函數;
- 3D縮放:包括scaleZ()和scale3d()兩個功能函數;
- 3D矩陣:和2D變形一樣,也有一個3D矩陣功能函數matrix3d()。
1、3D位移
translate3d()函數的語法:translate3d(tx,ty,tz)
參數說明:
- tx:代表橫坐標位移向量的長度;
- ty:代表縱坐標位移向量的長度;
- tz:代表Z軸位移向量的長度。不能為百分比值。
translateZ()函數的語法:translateZ(t)
,取值t指的是Z軸的向量位移長度。使用TranslateZ()可以讓元素在Z軸進行位移。為負值時,元素在Z軸越移越遠,導致元素變得較小;為正值時,元素在Z軸越移越近,導致元素變得較大。
translateZ()函數在實際使用中等同于translate3d(0,0,tz)。
2、3D縮放
當scale3d()中X軸和Y軸同時為1,即scale3d(1,1,sz),效果等同于scaleZ(sz)。
scale3d語法:scale3d(sx,sy,sz)
,可以讓元素在Z軸上按比例縮放。默認值為1,當值大于1時,元素放大;當值小于1大于0.01時,元素縮小。
scaleZ()語法:scaleZ(s)
,取值s指定每個點Z軸的比例。scaleZ(-1)定義了一個原點在Z軸的對稱點。
提示:scaleZ()和scale3d()函數單獨使用時沒有任何效果,需要配合其它變形函數一起使用時才有效果。
3、3D旋轉
在三維空間里,使用rotateX()、rotateY()和rotateZ()函數讓一個元素圍繞X、Y、Z軸旋轉。
語法:rotateX(a)|rotateY(a)|rotateZ(a)
,其中a指的是旋轉角度值,可以是正值,也可以是負值。為正值,元素順時針旋轉;為負值,元素逆時針旋轉。
rotate3d()函數也可以讓元素在三維空間中旋轉,軸的旋轉是由一個[x,y,z]向量并經過元素原點。語法:rotate3d(x,y,z,a)
參數說明:
- x:0~1的數值,用來描述元素圍繞X軸旋轉的矢量值;
- y:0~1的數值,用來描述元素圍繞Y軸旋轉的矢量值;
- z:0~1的數值,用來描述元素圍繞Z軸旋轉的矢量值;
- a:角度值,用來指定元素在3D空間旋轉的角度。正值時,元素順時針旋轉;負值時,元素逆時針旋轉。
當x、y、z取不同值時,和前面的三個旋轉函數功能等同:
- rotateX(a)函數功能等同于rotate3d(1,0,0,a);
- rotateY(a)函數功能等同于rotate3d(0,1,0,a);
- rotateZ(a)函數功能等同于rotate3d(0,0,1,a);
4、3D矩陣
語法:matrix3d(sx,0,0,0,0,sy,0,0,0,0,sz,0,0,0,0,1)
提示:傾斜是二維變形,不能在三維空間變形,元素可能會在X軸和Y軸傾斜,然后轉化為三維,但它們不能在Z軸傾斜。
5、多重變形
在CSS3中,不管是2D變形還是3D變形,都可以使用多重變形,它們之間使用空格分隔,語法:transform:<transform-function>|<transform-function>
其中,transform-function是指CSS3中的任何變形函數。
示例1:2D多重變形制作立方體
示例代碼:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>CSS3變形</title>
<style>
@keyframes spin{
0%{transform:rotateY(0deg)}
100%{transform:rotateY(360deg)}
}
.stage{
width:300px;
height: 300px;
float: left;
margin:15px;
background: url(img/background.png) no-repeat center center;
background-size:100% 100%;
position: relative;
perspective: 1200px;
}
.container{
position: relative;
height: 230px;
width:100px;
top:50%;
left: 50%;
margin:-100px 0 0 -50px;
transform-style: preserve-3d;
}
.container:hover{
animation: spin 5s linear infinite;
}
.side{
font-size:20px;
font-weight: bold;
height: 100px;
line-height: 100px;
color:#fff;
position: absolute;
text-align: center;
text-shadow: 0 -1px 0 rgba(0,0,0,0.2);
text-transform: uppercase;
width:100px;
}
.top{
background:#9acc53;
transform:rotate(-45deg) skew(15deg,15deg);
}
.left{
background:#8ec63f;
transform:rotate(15deg) skew(15deg,15deg) translate(-50%,100%);
}
.right{
background:#80b239;
transform:rotate(-15deg) skew(-15deg,-15deg) translate(50%,100%);
}
</style>
</head>
<body>
<div class="stage s1">
<div class="container">
<div class="side top">1</div>
<div class="side left">2</div>
<div class="side right">3</div>
</div>
</div>
</body>
</html>
示例圖2:3D多重變形制作立方體
示例代碼:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>CSS3變形</title>
<style>
@keyframes spin{
0%{transform:rotateY(0deg)}
100%{transform:rotateY(360deg)}
}
.stage{
width:300px;
height: 300px;
margin:15px auto;
background: url(img/background.png) no-repeat center center;
background-size:100% 100%;
position: relative;
perspective: 300px;
}
.container{
position: absolute;
height: 230px;
width:100px;
top:50%;
left: 50%;
margin:-100px 0 0 -100px;
transform:translateZ(-100px);
transform-style:preserve-3d;
}
.container:hover{
animation: spin 5s linear infinite;
}
.side{
background:rgba(142,198,63,0.3);
border:2px solid #8ec63f;
font-size: 60px;
font-weight: bold;
color:#fff;
height: 196px;
line-height: 196px;
position: absolute;
text-align: center;
text-shadow:0 -1px 0 rgba(0,0,0,0.2);
text-transform:uppercase;
width:196px;
}
.front{
transform:translateZ(100px);
}
.back{
transform:rotateX(180deg) translateZ(100px);
}
.top{
transform:rotateX(90deg) translateZ(100px);
}
.left{
transform:rotateY(-90deg) translateZ(100px);
}
.right{
transform:rotateY(90deg) translateZ(100px);
}
.bottom{
transform:rotateX(-90deg) translateZ(100px);
}
</style>
</head>
<body>
<div class="stage s1">
<div class="container">
<div class="side front">1</div>
<div class="side back">2</div>
<div class="side left">3</div>
<div class="side right">4</div>
<div class="side top">5</div>
<div class="side bottom">6</div>
</div>
</div>
</body>
</html>