transform本質上是一系列變形函數,分別是translate位移,scale縮放,rotate旋轉,skew扭曲,matrix矩陣。css
用於指定元素變形的中心點。默認中心點就是元素的正中心,即XYZ軸的50% 50% 0處。能夠經過該屬性改變元素在XYZ軸的中心點,正值表示正向位移,負值表示負向位移。(XYZ軸的正向分別是往右,往下,靠近用戶眼睛。反之爲反向)api
表示2維的x-offset/y-offset
能夠設px值也能夠設%百分比,也可設top / right / bottom / left / center
等keyword。表示3維的z-offset
只能設px值,不能設%百分比,也沒有keyword。瀏覽器
默認中心點在元素正中心,所以關鍵字top等價於top center等價於50% 0%(x軸仍舊留在50%處,y軸位移到0%處)。同理各關鍵字例如right等價於right center等價於100% 50%,很少贅述。函數
一圖勝千言:爲圖片設置不一樣的中心點後,看它們旋轉,扭曲,縮放的效果。例如圖1表頭的第一行center表示transform-origin: center
。第二行rotate(30deg);表示transform: rotate(30deg);
。佈局
另外transform-origin指定變形中心點對translate位移沒有影響。translate位移始終相對於元素正中心進行位移,有懷疑精神的能夠本身試一下。動畫
這個屬性比較簡單隻有兩個值flat
和preserve-3d
。用於指定舞臺爲2D或3D,默認值flat表示2D舞臺,全部子元素2D層面展示。preserve-3d看名字就知道了表示3D舞臺,全部子元素在3D層面展示。注意,在變形元素自身上指定該屬性是沒有用的,它用於指定舞臺,因此要在變形元素的父元素上設置該屬性。設定後,全部子元素共享該舞臺。一圖勝千言:spa
.div1 {
float: left;
background-color: red;
transform: perspective(200px) rotateY(45deg);
}
.div1 img{
transform: translateZ(16px);
}
.p3d {
transform-style: preserve-3d;
}
<div class="div1"><img src="head75.png" /></div> <div class="div1 p3d"><img src="head75.png" /></div>
兩圖惟一的區別是:右圖的父div上設了transform-style: preserve-3d;
,所以呈現了3d效果。左圖的父div沒有設transform-style默認是flat,所以元素不會在Z軸展開(translateZ(16px)失效),只能呈現2D效果。scala
另外若是同時設了transform-style: preserve-3d;
和overflow: hidden;
,3D效果將失效,等價於transform-style: flat;
。若是你發現3D效果沒有像預想地那樣出現,能夠檢查一下(包括祖先元素)是否有overflow: hidden;
,該屬性將flatten everything…3d
指定3D的視距。默認值是none表示無3D效果,即2D扁平化。上面例子代碼裏其實已經用到過該屬性了。介紹它以前,先借用rotateX / rotateY / rotateZ來明確一下xyz軸座標的基本概念。一圖勝千言,依次是rotateX軸旋轉,rotateY軸旋轉,rotateZ軸旋轉:code
.x {
transform: perspective(200px) rotateX(60deg); } .y { transform: perspective(200px) rotateY(60deg); } .z { transform: perspective(200px) rotateZ(60deg); } <img class="x" src="head75.png" /> <img class="y" src="head75.png" /> <img class="z" src="head75.png" />
從圖中也能夠看出,烤羊肉串就是x軸旋轉,鋼管舞就是y軸旋轉,彩票轉盤就是z軸旋轉。上面z軸只是一個點,想象一下就能明白,該點實際上是一根垂直於屏幕的線,而perspective視距就是該線從屏幕到用戶眼睛的距離。
實現3D的關鍵就是要有perspective視距,若是將上述代碼中perspective(200px)
去掉,效果以下:
除了z軸旋轉不受影響外,xy軸雖然還在旋轉,但失去了3D效果,是2D扁平化的旋轉。緣由就是由於不設perspective的話,其默認值爲none,沒有視距沒有3D。
perspective只能設px值,不能設%百分比。值越小表示用戶眼睛距離屏幕越近,至關於建立一個較大的3D舞臺。反之,值越大表示用戶眼睛距離屏幕越遠,至關於建立一個較小的3D舞臺。這很容易理解,離的越近東西看起來越大,離的越遠東西看起來越小。但具體該怎麼設呢?借用W3C的圖配合translateZ來幫助理解視距。
圖中d就是perspective視距,Z就是translateZ軸的位移。Z軸正向位移時,3D舞臺將放大。反之,Z軸負向位移時,3D舞臺將縮小。上圖Z是d的一半,所以3D舞臺上的元素將是原來的2倍。下圖Z一樣是d的一半,但因爲是負值,因此3D舞臺上的元素將縮小三分之一。實際試試:
.divsp {
display: inline-block;
border: 1px blue dashed; margin-left: 30px; perspective: 100px; } .z1 { transform: translateZ(-75px); } .z2 { transform: translateZ(0px); } .z3 { transform: translateZ(25px); } .z4 { transform: translateZ(101px); } <div class="divsp"><img class="z1" src="head75.png" /></div> <div class="divsp"><img class="z2" src="head75.png" /></div> <div class="divsp"><img class="z3" src="head75.png" /></div> <div class="divsp"><img class="z4" src="head75.png" /></div>
4張圖的視距都是100px,表示4張圖的3D舞臺距離你的眼睛100px。咱們從右往左來理解。圖4的translateZ(101px)
看到圖片消失了,由於3D舞臺距離你眼睛100px,而圖片從舞臺往Z軸正向位移101px,圖片到了你腦殼後面天然什麼都看不見。若是設成translateZ(100px)
,至關於圖片緊貼着你的眼睛,因此全屏都是圖片。圖3的translateZ(25px)
,原始圖片爲75px,放大後的圖片爲100px。這是道初中數學題,你能夠畫一個底邊是75px(圖片原始尺寸),高是75px(視距100px-Z軸位移25px=75px)的等腰三角形,而後高擴展到100px,底邊將等比例擴大3分之1至100px。圖2的translateZ(0px)
表示Z軸沒有位移,所以仍舊是原始大小。圖4的translateZ(-75px)
,一樣是道初中數學題,原始圖片爲75px,縮小到42.85px,再看看上面W3C的圖理解一下,很容易算出來。
仔細看代碼的能夠看出來,上面介紹XYZ軸旋轉時是直接在變形元素img上指定的transform: perspective(200px) rotateX(60deg);
。而上面的代碼是給變形元素img的父div指定perspective: 100px;
。你能夠理解爲前一種方式是perspective()函數,後一種方式是perspective屬性。兩種指定方式是有區別的:
設置視距的基點,看W3C的圖就能明白
基點默認值是50% 50%即center,表示視距基點在中心點不進行任何位移。你可讓基點在XY軸上進行位移,產生上圖那樣的效果。注意該屬性一樣應該定義在父元素上,適用於整個3D舞臺。它須要和perspective屬性結合着一塊兒用。效果以下圖:
.td1 { transform-style: preserve-3d; perspective: 200px; perspective-origin: center; }
爲節約篇幅,只貼出來圖1的3D舞臺的配置,其他8圖只需根據表頭修改perspective-origin便可。根據上面9宮格圖就比較容易理解perspective-origin視距基點的意思了。默認值50% 50%即center表示眼睛在舞臺正中心。而後根據XY軸的位移量,或關鍵字left(等價於x軸0%)等,調整眼睛看3D舞臺的位置。
用因而否能夠看見3D舞臺背面,默認值visible表示背面可見,能夠設成hidden讓背面不可見。一般當旋轉時,若是不但願背面顯示出來,該屬性就頗有用,設成hidden便可。一圖勝千言:
.stage{
float: left; margin: 5px; perspective: 200px; } .container { transform-style: preserve-3d; } .image { backface-visibility: hidden; } .front { position: absolute; z-index: 1; } .back { transform: rotateY(180deg); } .stage:nth-child(1) .container{ transform: rotateY(0deg); } .stage:nth-child(2) .container{ transform: rotateY(30deg); } .stage:nth-child(3) .container{ transform: rotateY(60deg); } .stage:nth-child(4) .container{ transform: rotateY(90deg); } .stage:nth-child(5) .container{ transform: rotateY(120deg); } .stage:nth-child(6) .container{ transform: rotateY(150deg); } .stage:nth-child(7) .container{ transform: rotateY(180deg); } <div class="stage"> //爲節約篇幅該DOM請無腦複製7個 <div class="container"> <img class="image front" src="head75.png" /> <img class="image back" src="bg75.png" /> </div> </div>
DOM結構中就能看出,是兩張圖片(一正一反)疊在了一塊兒。因爲變形元素img設了backface-visibility: hidden;
,當Y軸旋轉超過90度時(Y軸旋轉正好90度時,正中間圖4爲一片空白,就像丁字褲在視線裏消失了^_^),正面的圖片將不可見,底下的背面圖片顯示出來了。若是將img的backface-visibility屬性去掉(默認爲visibility),效果以下圖。Y軸旋轉超過90度時,將顯示正面的圖片的背部(所謂背部對屏幕來講其實就是圖片矩陣的X軸值取反):
至此5個前置屬性介紹完畢。它們多用於3D場合,所以常見的3D的HTML結構以下:
<舞臺> //爲舞臺加上perspective <容器> //爲容器加上preserve-3d,使容器內元素共享同一個3D渲染環境 <元素> //爲元素加上transform效果 </容器> </舞臺>
2D變形有translate位移,scale縮放,rotate旋轉,skew扭曲,matrix矩陣。基本的內容就不細說了,自行參照w3cschool,這裏只介紹一些w3cschool上沒有講的內容。
translate位移系列中用於2D的有:translate,translateX,translateY
translate位移,相似於position:relative屬性。可設單值,也可設雙值。正數表示XY軸正向位移,負數爲反向位移。設單值表示只X軸位移,Y軸座標不變,例如transform: translate(100px);
等價於transform: translate(100px,0);
。這點和CSS中其餘單值屬性稍有不一樣,不要誤覺得單值是X軸和Y軸均位移。固然最好仍是用雙值,若是真的和Y軸無關,也請用translateX(100px)
,雖然效果是同樣的,但代碼可讀性更高。同理若是和X軸無關,能夠用transform: translateY(100px);
等價於transform: translate(0, 100px);
上面說了效果相似於position:relative屬性,但和position語義不一樣,position用於頁面佈局,而translate屬於transform中的一個系列,用於元素變形。你可能以爲語義不一樣有什麼卵用,效果OK不就好了?就看你用什麼標準來衡量效果了。CSS的神奇之處在於你能夠將一個屬性用在徹底違背它原意的場景下,拋開代碼可讀性不談,違背原意有時仍是會有細微差異的。如結合動畫效果時,translate能小於1px過渡,所以動畫效果更爲平滑。但position最小單位就是1px,動畫效果確定打折扣。另外用translate實現動畫時,可使用GPU,動畫的FPS更高,而position顯然沒法享受這個優點。其餘如迴流和重繪也都有差別。所以若是你在該用translate的地方用了position,從此一些需求變更達不到要求,你也沒什麼立場可抱怨的了。
scale縮放系列中用於2D的有:scale,scaleX,scaleY
scale縮放,一樣能夠設單值和雙值。單值時表示X軸和Y軸等值縮放。默認值爲1,要縮小請設0.01~0.99之間的值,要放大請設超過1的值。例如縮小一倍能夠transform: scale(.5);
,放大一倍能夠transform: scale(2);
。效果在最上面介紹transform-origin時圖片裏已經有了,很少贅述。
若是隻想X軸縮放,能夠用scaleX(.5)
至關於scale(.5, 1)
。同理只想Y軸縮放,能夠用scaleY(.5)
至關於scale(1, .5)
。
設雙值能夠實現X軸Y軸不等比例縮放,如transform: scale(.5, 1.5);
,本來75*75px的圖片變成了37.5*112.5px大小。如左圖:
w3cschool上沒說的是,scale還能設負數,負數會先將元素反轉再縮放,如transform: scale(-.5, -1.5);
,效果見上面右圖。爲什麼反轉能理解吧?XY軸像素矩陣各值取反後,效果等價於反轉。固然你一樣能夠用rotate實現反轉。
rotate旋轉系列中用於2D的有:rotate
rotate旋轉,比較簡單,只能設單值。正數表示順時針旋轉,負數表示逆時針旋轉。如transform: rotate(30deg);
,效果在最上面介紹transform-origin時圖片裏已經有了,很少贅述。(注意和上面不一樣,在2D層面上沒有rotateX / rotateY,它倆和rotateZ都是3D旋轉)
skew扭曲系列中用於2D的有:skew,skewX,skewY
skew扭曲能夠設單值和雙值。單值時表示只X軸扭曲,Y軸不變,如transform: skew(30deg);
等價於transform: skew(30deg, 0);
。考慮到可讀性,不推薦用單值,應該用transform: skewX(30deg);
。skewY表示只Y軸扭曲,X軸不變。效果在最上面介紹transform-origin時圖片裏已經有了,很少贅述。
matrix矩陣前面沒有直接接觸,但倒是全部2D變形的本質,上面全部2D變形效果均可以用matrix矩陣來實現。本篇先略過,將它和3D矩陣matrix3d留到下一篇再介紹。
3D變形有translate3d位移,scale3d縮放,rotate3d旋轉, matrix3d矩陣。(注意skew扭曲是沒有3D的)。3D的用法和2D差很少,只不過多了個Z軸的值而已(這不是廢話麼…)。
translate3d位移系列中用於3D的有:translate3d,translateZ
translate3d(tx,ty,tz),其中tz的Z軸長度只能爲px值,不能爲%百分比。translateZ等價於translate3d(0,0,tz)
。Z軸的值越大表示離眼睛越近,元素就越大,但當值大於perspective視距時元素將消失,由於眼睛沒法看見眼睛背後的東西,這在上面介紹perspective時已經介紹過,再也不贅述。值越小表示離眼睛越遠,元素就越小。實際使用中translateZ效果和2D的scale縮放效果很是像,但原理是有區別的,translateZ是Z軸上位移,而scale是XY軸的縮放。仍是那句話,儘可能將屬性用在符合屬性願意的場合。
scale3d縮放系列中用於3D的有:scale3d,scaleZ
scale3d(sx,sy,sz),其中sz爲Z軸的縮放比例,取值同sx,sy同樣,在0.01~0.99時元素縮小,1時大小不變,大於1時元素變大。scaleZ等價於scale(1,1,sz)
。須要注意的是單獨使用scale3d或scaleZ不會有任何效果,須要配合其餘屬性在3D舞臺上才能出現效果,不然Z軸的縮放比例根本沒法定義。
rotate3d旋轉系列中用於3D的有:rotate3d,rotateX,rotateY,rotateZ
rotate3d(x,y,z,a)這裏多了一個參數a(讀音是阿爾法…)表示3D舞臺上旋轉的角度,而xyz的取值爲0~1爲各軸的旋轉矢量值。rotate3d,rotateX,rotateY,rotateZ的效果在上面都有展現,不贅述。
最後matrix3d矩陣是全部3D變形的本質,上面全部3D變形效果均可以用matrix3d矩陣來實現。本篇先略過,將它和上面的2D矩陣matrix留到下一篇再介紹。
如今來看看變形對CSS層級的影響。提及層級,absolute絕對是層級間的高富帥,見一個睡一個,sorry,是見一個壓一個,sorry,是見一個覆蓋一個。
//左圖
<img style="position:absolute;" src="bg100.png" /> <img src="head75.png" /> //右圖 <img style="position:absolute;" src="bg100.png" /> <img style="transform:scale(1);" src="head75.png" />
左圖由於第一張img具備absolute,徹底無視DOM結構中的順序,妥妥地覆蓋了第二張img。右圖給第二張img設了transform,一般咱們會認爲scale(1)
是廢代碼,但實際從右圖已經看出,因爲設立transform,使元素具備了至關於absolute的層級,所以兩張img平級了,根據DOM中的順序,後者覆蓋了前者。
(這裏使用的是scale,你能夠改爲rotate,skew等,效果都同樣。即層級和transform有關,但和具體哪一個transform函數無關)
由於absolute和transform平級,你能夠調整上面兩張img的順序,這樣設了transform的圖片會被absolute覆蓋。若是你非要讓absolute高人一等,能夠設z-index:1
這樣層級會高於transform,達到覆蓋效果。
和absolute同系列的relative和fixed也適用上述層級關係。若是你頁面上有個fixed廣告標籤,頁面滾動時被transform元素覆蓋了,請不要驚訝,試試設一下z-index。
transform變形的用法介紹到這就差很少了。爲縮減篇幅,文中代碼都省略-ms,-o等前綴,須要瀏覽器全適應的請自行加上。下一篇matrix/matrix3d會更深刻其本質,看看這些變形函數到底是如何變換座標位置,顯示出各類效果的。