CSS里transform變形這個屬性有點學習難度承耿,尤其在CSS3里加上了3D效果之后,2維變3維學習成本更是成倍提高伪煤。為什么設計師的眼里飽含著淚水加袋,因為對頁面效果愛的深沉。本篇就介紹一下transform抱既。(擎天柱:Autobot transform!)
transform本質上是一系列變形函數(shù)职烧,分別是translate位移,scale縮放,rotate旋轉蚀之,skew扭曲蝗敢,matrix矩陣。戒驕戒躁足删,我們一個個講寿谴。
前置屬性:
transform-origin
transform-style
perspective
perspective-origin
backface-visibility
2D變形:
translate
scale
rotate
skew
matrix
3D變形:
translate3d
scale3d
rotate3d
matrix3d
層級影響
前置屬性
transform-origin
用于指定元素變形的中心點。默認中心點就是元素的正中心壹堰,即XYZ軸的50% 50% 0處拭卿。可以通過該屬性改變元素在XYZ軸的中心點贱纠,正值表示正向位移峻厚,負值表示負向位移。(XYZ軸的正向分別是往右谆焊,往下惠桃,靠近用戶眼睛。反之為反向)
表示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位移始終相對于元素正中心進行位移,有懷疑精神的可以自己試一下燕鸽。
其實transform-origin只是一個語法糖而已赊豌,你總是可以用translate來代替它。每個transform-origin都可以被兩個translate模擬出來(by CSS變形規(guī)范的編輯Aryeh Gregor)绵咱。例如:
transform: rotate(30deg);
transform-origin: 200px 300px;
//等價于
transform: translate(200px, 300px)
rotate(30deg)
translate(-200px, -300px);
transform-origin: 0 0;
transform-style
這個屬性比較簡單只有兩個值flat
和preserve-3d
。用于指定舞臺為2D或3D,默認值flat表示2D舞臺悲伶,所有子元素2D層面展現(xiàn)艾恼。preserve-3d看名字就知道了表示3D舞臺,所有子元素在3D層面展現(xiàn)麸锉。注意钠绍,在變形元素自身上指定該屬性是沒有用的,它用于指定舞臺花沉,所以要在變形元素的父元素上設置該屬性柳爽。設定后,所有子元素共享該舞臺碱屁。一圖勝千言:
.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>
兩圖唯一的區(qū)別是:右圖的父div上設了transform-style: preserve-3d;
磷脯,因此呈現(xiàn)了3d效果。左圖的父div沒有設transform-style默認是flat娩脾,因此元素不會在Z軸展開(translateZ(16px)失效)赵誓,只能呈現(xiàn)2D效果。
另外如果同時設了transform-style: preserve-3d;
和overflow: hidden;
柿赊,3D效果將失效俩功,等價于transform-style: flat;
。如果你發(fā)現(xiàn)3D效果沒有像預想地那樣出現(xiàn),可以檢查一下(包括祖先元素)是否有overflow: hidden;
,該屬性將flatten everything…
perspective
指定3D的視距洽腺。默認值是none表示無3D效果核无,即2D扁平化炼彪。上面例子代碼里其實已經用到過該屬性了。介紹它之前萄唇,先借用rotateX / rotateY / rotateZ來明確一下xyz軸坐標的基本概念四敞。一圖勝千言癌蚁,依次是rotateX軸旋轉咬摇,rotateY軸旋轉缕减,rotateZ軸旋轉:
.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視距就是該線從屏幕到用戶眼睛的距離掸茅。
實現(xiàn)3D的關鍵就是要有perspective視距昧狮,如果將上述代碼中perspective(200px)
去掉沪悲,效果如下:
除了z軸旋轉不受影響外门岔,xy軸雖然還在旋轉,但失去了3D效果,是2D扁平化的旋轉妻往。原因就是因為不設perspective的話,其默認值為none试和,沒有視距沒有3D讯泣。
perspective只能設px值,不能設%百分比阅悍。值越小表示用戶眼睛距離屏幕越近好渠,相當于創(chuàng)建一個較大的3D舞臺。反之节视,值越大表示用戶眼睛距離屏幕越遠拳锚,相當于創(chuàng)建一個較小的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忱嘹。這是道初中數(shù)學題,你可以畫一個底邊是75px(圖片原始尺寸)耕渴,高是75px(視距100px-Z軸位移25px=75px)的等腰三角形,然后高擴展到100px齿兔,底邊將等比例擴大3分之1至100px橱脸。圖2的translateZ(0px)
表示Z軸沒有位移,因此仍舊是原始大小分苇。圖4的translateZ(-75px)
添诉,同樣是道初中數(shù)學題,原始圖片為75px医寿,縮小到42.85px栏赴,再看看上面W3C的圖理解一下,很容易算出來靖秩。
仔細看代碼的可以看出來须眷,上面介紹XYZ軸旋轉時是直接在變形元素img上指定的transform: perspective(200px) rotateX(60deg);
。而上面的代碼是給變形元素img的父div指定perspective: 100px;
沟突。你可以理解為前一種方式是perspective()函數(shù)花颗,后一種方式是perspective屬性。兩種指定方式是有區(qū)別的:
前者perspective()函數(shù)指定只針對當前變形元素惠拭,需要和transform其他函數(shù)一起使用扩劝,僅表示當前變形元素的視距。
后者perspective屬性指定用于3D舞臺职辅,即3D舞臺的視距棒呛,里面的子元素共享這個視距
perspective-origin
設置視距的基點,看W3C的圖就能明白
基點默認值是50% 50%即center域携,表示視距基點在中心點不進行任何位移簇秒。你可以讓基點在XY軸上進行位移,產生上圖那樣的效果涵亏。注意該屬性同樣應該定義在父元素上宰睡,適用于整個3D舞臺蒲凶。它需要和perspective屬性結合著一起用。效果如下圖:
.td1 {
transform-style: preserve-3d;
perspective: 200px;
perspective-origin: center;
}
為節(jié)約篇幅拆内,只貼出來圖1的3D舞臺的配置旋圆,其余8圖只需根據表頭修改perspective-origin即可。根據上面9宮格圖就比較容易理解perspective-origin視距基點的意思了麸恍。默認值50% 50%即center表示眼睛在舞臺正中心灵巧。然后根據XY軸的位移量,或關鍵字left(等價于x軸0%)等抹沪,調整眼睛看3D舞臺的位置刻肄。
backface-visibility
用于是否可以看見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"> //為節(jié)約篇幅該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渲染環(huán)境
<元素> //為元素加上transform效果
</容器>
</舞臺>
2D變形
2D變形有translate位移,scale縮放缘琅,rotate旋轉粘都,skew扭曲,matrix矩陣刷袍◆嫠恚基本的內容就不細說了,自行參照w3cschool呻纹,這里只介紹一些w3cschool上沒有講的內容堆生。
translate位移
translate位移系列中用于2D的有:translate专缠,translateX,translateY
translate位移淑仆,類似于position:relative屬性涝婉。可設單值蔗怠,也可設雙值墩弯。正數(shù)表示XY軸正向位移,負數(shù)為反向位移寞射。設單值表示只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實現(xiàn)動畫時,可以使用GPU窗宦,動畫的FPS更高赦颇,而position顯然無法享受這個優(yōu)勢二鳄。其他如回流和重繪也都有差異。因此如果你在該用translate的地方用了position媒怯,今后一些需求變動達不到要求订讼,你也沒什么立場可抱怨的了。
scale縮放
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)
敢课。
設雙值可以實現(xiàn)X軸Y軸不等比例縮放阶祭,如transform: scale(.5, 1.5);
,原本7575px的圖片變成了37.5112.5px大小直秆。如左圖:
w3cschool上沒說的是濒募,scale還能設負數(shù),負數(shù)會先將元素反轉再縮放圾结,如transform: scale(-.5, -1.5);
瑰剃,效果見上面右圖。為何反轉能理解吧筝野?XY軸像素矩陣各值取反后晌姚,效果等價于反轉。當然你同樣可以用rotate實現(xiàn)反轉歇竟。
rotate旋轉
rotate旋轉系列中用于2D的有:rotate
rotate旋轉舀凛,比較簡單,只能設單值途蒋。正數(shù)表示順時針旋轉猛遍,負數(shù)表示逆時針旋轉。如transform: rotate(30deg);
,效果在最上面介紹transform-origin時圖片里已經有了懊烤,不多贅述梯醒。(注意和上面不同,在2D層面上沒有rotateX / rotateY腌紧,它倆和rotateZ都是3D旋轉)
skew扭曲
skew扭曲系列中用于2D的有:skew茸习,skewX,skewY
skew扭曲可以設單值和雙值壁肋。單值時表示只X軸扭曲号胚,Y軸不變,如transform: skew(30deg);
等價于transform: skew(30deg, 0);
浸遗∶ㄐ玻考慮到可讀性,不推薦用單值跛锌,應該用transform: skewX(30deg);
弃秆。skewY表示只Y軸扭曲,X軸不變髓帽。效果在最上面介紹transform-origin時圖片里已經有了菠赚,不多贅述。
matrix矩陣
matrix矩陣前面沒有直接接觸郑藏,但卻是所有2D變形的本質酬滤,上面所有2D變形效果都可以用matrix矩陣來實現(xiàn)兆旬。本篇先略過辰如,將它和3D矩陣matrix3d留到下一篇再介紹劣纲。
3D變形
3D變形有translate3d位移,scale3d縮放筑悴,rotate3d旋轉, matrix3d矩陣稍途。(注意skew扭曲是沒有3D的)阁吝。3D的用法和2D差不多,只不過多了個Z軸的值而已(這不是廢話么…)械拍。
translate3d位移
translate3d位移系列中用于3D的有:translate3d突勇,translateZ
translate3d(tx,ty,tz),其中tz的Z軸長度只能為px值坷虑,不能為%百分比甲馋。translateZ等價于translate3d(0,0,tz)
。Z軸的值越大表示離眼睛越近迄损,元素就越大定躏,但當值大于perspective視距時元素將消失,因為眼睛無法看見眼睛背后的東西,這在上面介紹perspective時已經介紹過痊远,不再贅述垮抗。值越小表示離眼睛越遠,元素就越小碧聪。實際使用中translateZ效果和2D的scale縮放效果非常像冒版,但原理是有區(qū)別的,translateZ是Z軸上位移逞姿,而scale是XY軸的縮放辞嗡。還是那句話,盡量將屬性用在符合屬性愿意的場合滞造。
scale3d縮放
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舞臺上才能出現(xiàn)效果,否則Z軸的縮放比例根本無法定義疆虚。
rotate3d旋轉
rotate3d旋轉系列中用于3D的有:rotate3d苛败,rotateX,rotateY径簿,rotateZ
rotate3d(x,y,z,a)這里多了一個參數(shù)a(讀音是阿爾法…)表示3D舞臺上旋轉的角度罢屈,而xyz的取值為0~1為各軸的旋轉矢量值。rotate3d篇亭,rotateX缠捌,rotateY,rotateZ的效果在上面都有展示译蒂,不贅述曼月。
matrix3d矩陣
最后matrix3d矩陣是所有3D變形的本質,上面所有3D變形效果都可以用matrix3d矩陣來實現(xiàn)柔昼。本篇先略過哑芹,將它和上面的2D矩陣matrix留到下一篇再介紹。
層級影響
現(xiàn)在來看看變形對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函數(shù)無關)
因為absolute和transform平級,你可以調整上面兩張img的順序榄鉴,這樣設了transform的圖片會被absolute覆蓋履磨。如果你非要讓absolute高人一等,可以設z-index:1
這樣層級會高于transform庆尘,達到覆蓋效果剃诅。
和absolute同系列的relative和fixed也適用上述層級關系。如果你頁面上有個fixed廣告標簽驶忌,頁面滾動時被transform元素覆蓋了矛辕,請不要驚訝,試試設一下z-index位岔。
總結
transform變形的用法介紹到這就差不多了如筛。為縮減篇幅堡牡,文中代碼都省略-ms抒抬,-o等前綴,需要瀏覽器全適應的請自行加上晤柄。下一篇matrix/matrix3d會更深入其本質擦剑,看看這些變形函數(shù)究竟是如何變換坐標位置,顯示出各種效果的。
作者:張歆琳
鏈接:http://www.reibang.com/p/17e289fcf467
來源:簡書
著作權歸作者所有惠勒。商業(yè)轉載請聯(lián)系作者獲得授權赚抡,非商業(yè)轉載請注明出處。</pre>