學(xué)會(huì)使用CSS3 transform 變形

第一部分:變形介紹

image

自層疊樣式表誕生以來,元素始終是矩形的,而且只能沿著橫軸和縱軸放置。有些技巧能讓元素看起來是傾斜的,但是底層的坐標(biāo)方格并沒有變形。CSS變形功能改變了這一現(xiàn)狀,能以不同的方式改變對(duì)象的形態(tài),而且還不只限于二維。

不論你想要旋轉(zhuǎn)照片,翻轉(zhuǎn)元素等功能使用CSS的變形功能都能做到,CSS變形功能分為2D和3D變形。

image

CSS變形功能包括:

  • 移動(dòng)(translate)
  • 縮放(scale)
  • 旋轉(zhuǎn)(rotate)
  • 傾斜(skew)

第二部分:坐標(biāo)系

學(xué)習(xí)變形之前,先需要了解一下變形中的坐標(biāo)系。在CSS中,笛卡爾坐標(biāo)系使用三個(gè)軸表示(如下圖):

  • x軸(橫軸)
  • y軸(縱軸)
  • z軸(深度軸)
變形功能表示笛卡爾坐標(biāo)系的三個(gè)軸

2D變形只需要關(guān)注x軸和y軸。

x軸的正值在右側(cè),負(fù)值在左側(cè)。y軸的正值沿縱軸向下,負(fù)值沿縱軸向上?;叵胍幌露ㄎ辉氐膖op屬性:值為正數(shù)時(shí)元素下移,值為負(fù)數(shù)時(shí)元素上移。

如果想把元素向左下方移動(dòng),要把x值設(shè)為負(fù)數(shù),把y值設(shè)為正數(shù):

 transform: translateX(-5em) translateY(50px);
image

上面這個(gè)變形是有效的。上面代碼的作用是把元素向左移動(dòng)5em,向下移動(dòng)50像素。

3D變形不僅需要關(guān)注x軸和y軸,還要加上z軸。

z軸從顯示器上躍出,指向你的眼前。z軸上的正值離你較近,負(fù)值離你較遠(yuǎn)。定位元素的z-index屬性是和它完全一樣的。

在上面的基礎(chǔ)上再加個(gè)z軸值:

 transform: translateX(-5em) translateY(50px) translateZ(200px);

與未指定z值相比,元素離我們的距離近了200像素?,F(xiàn)在還看不到效果,等介紹到3D變形的時(shí)候就會(huì)感受到變化了。

2.1 移動(dòng)參照物

每個(gè)元素都有自己的參照物,各軸都相對(duì)自身而動(dòng)。如果旋轉(zhuǎn)了元素,軸也隨之旋轉(zhuǎn)。旋轉(zhuǎn)之后再變形,是相對(duì)旋轉(zhuǎn)后的軸計(jì)算的,而不是顯示器的軸。如下圖:

image

CSS變形功能中使用的另一個(gè)坐標(biāo)系——球坐標(biāo)系。這個(gè)坐標(biāo)系用于描述3D空間中的角度。如下圖:

image

在2D變形中只需要關(guān)注全周360度坐標(biāo)系,即由x軸和y軸構(gòu)成的屏幕。對(duì)旋轉(zhuǎn)來說,2D旋轉(zhuǎn)其實(shí)是在繞z軸旋轉(zhuǎn)。類似的,如果繞x軸旋轉(zhuǎn),元素將偏向我們或遠(yuǎn)離我們,而繞y軸旋轉(zhuǎn)的話,元素將向兩側(cè)旋轉(zhuǎn),如下圖(需要仔細(xì)理解):

  • 繞x軸旋轉(zhuǎn)


    image
  • 繞y軸旋轉(zhuǎn)

image
  • 繞z軸旋轉(zhuǎn)
image
image

在2D旋轉(zhuǎn)中,假設(shè)我們要在顯示器屏幕上(即繞z軸)順時(shí)針旋轉(zhuǎn)一個(gè)元素45度,使用的變形值可以是下面這樣的:

transform: rotate(45deg);

如果把值改為-45deg,元素將繞z軸軸逆時(shí)針旋轉(zhuǎn)。換句話說,元素在xy平面上旋轉(zhuǎn)。如下圖:

image

第三部分:變形語法和注意事項(xiàng)

變形其實(shí)只有一個(gè)屬性,但是有幾個(gè)輔助屬性用于控制如何變形。Transform使用如下表格:

Transform
取值 <transform-list> none
初始值 None
適用于 除 “基元行內(nèi)”框之外的所有元素“
百分?jǐn)?shù) 相對(duì)范圍框計(jì)算
計(jì)算值 指定的值,不過相對(duì)長度值會(huì)計(jì)算為絕對(duì)長度
繼承性
動(dòng)畫性 變形
說明:
  1. 范圍框:元素邊框的外邊界。也就是說,計(jì)算范圍框時(shí),輪廓和外邊距不算在內(nèi)。

  2. 變形的元素有自己的堆疊上下文。經(jīng)過縮放的元素可能比變形前小或大,不過元素在頁面上所占的空間與變形前保持不變。對(duì)所有變形函數(shù)都成立。

  3. <transform-list> | none 表示一個(gè)或多個(gè)變形函數(shù),中間以空格分隔。如:transform: rotate(30deg) skewX(-25deg) scaleY(2);

  4. 變形函數(shù)一次只處理一個(gè),從最左邊第一個(gè)開始,一直到最后一個(gè)。從頭到尾的處理順序很重要。順序變了,得到的結(jié)果就有可能會(huì)不同。

  5. 有多個(gè)變形函數(shù)時(shí),每個(gè)都要設(shè)置正確,要確保全部有效。如果有一個(gè)函數(shù)是無效的,整個(gè)值都將失效。

  6. 變形通常不疊加。如果改變了元素的形態(tài),而后再想添加一種變形,那么要在原變形基礎(chǔ)上修改。就像你在一個(gè)地方聲明了字號(hào),又在另一個(gè)地方為元素聲明了不同的字號(hào)一樣,字號(hào)是不疊加的。只有其中一個(gè)字號(hào)起作用。不過動(dòng)畫變形除外,不管使用過渡還是真正的動(dòng)畫,效果是疊加的。

  7. 變形現(xiàn)在還不能應(yīng)用到基元行內(nèi)框上?;袃?nèi)框指span,超鏈接等行內(nèi)框。這些元素可以隨著塊級(jí)父元素一起變形,但是不能直接旋轉(zhuǎn)。除非把它們的顯示方式改為display:block,display:inline-block等。

transform: translateX(200px) rotate(45deg);
transform: rotate(45deg) translateX(200px);
不同順序,不同結(jié)果
div {transform: translateX(100px) scale(1.2)};
div:hover {transform:rotate(-45deg)};

即使不顯式使用過渡或動(dòng)畫,也能通過用戶交互偽類(如:hover)實(shí)現(xiàn)疊加變形。這是因?yàn)閼彝5刃Ч褪且环N過渡,只不過不是由過渡屬性觸發(fā)的。因此可以向上面這樣聲明變形屬性進(jìn)行效果疊加。

變形函數(shù)

變形函數(shù)目前一共有21個(gè)。不同的變形函數(shù)利用不同格式的值實(shí)現(xiàn)相應(yīng)的變形。

  1. translate()
  2. translate3d()
  3. translateX()
  4. translateY()
  5. translateZ()
  6. scale()
  7. scale3d()
  8. scaleX()
  9. scaleY()
  10. scaleZ()
  11. rotate()
  12. rotate3d()
  13. rotateX()
  14. rotateY()
  15. rotateZ()
  16. skew()
  17. skewX()
  18. skewY()
  19. matrix()
  20. matrix3d()
  21. perspective()

具體語法可以參考這篇文章。非常詳細(xì)的介紹了每個(gè)函數(shù)的具體用法。

第四部分:平移函數(shù) translate()

平移函數(shù)沿一個(gè)軸或多個(gè)軸移動(dòng)。

  • translateX()沿元素自身的x軸移動(dòng)元素。
  • translateY()沿元素自身的y軸移動(dòng)元素。
  • translateZ()沿元素自身的z軸移動(dòng)元素。
函數(shù) 可取值
translateX(),translateY() `<length> <percentage> `
translateZ() <length>
translate() `[<length> <percentage>][,<length> <percentage>]?`
translate3d() `[<length> <percentage>][<length> <percentage>],[<length>]`
4.1 translateX(),translateY()

translateX(),translateY()這兩個(gè)通常成為“2D”平移函數(shù),因?yàn)樗鼈兡苌舷乱苿?dòng)元素,也能左右移動(dòng)元素。但是不能沿著z軸前后移動(dòng)元素。這兩個(gè)函數(shù)的值都是一個(gè)距離值,可以是長度,也可以是百分比。

translateX(200px)  <!--元素向右移動(dòng)200像素-->
translateY(200px)  <!--元素向下移動(dòng)200像素-->

如果值是百分?jǐn)?shù),移動(dòng)距離相對(duì)元素自身的尺寸計(jì)算。

translateX(50%)  <!--元素向右移動(dòng)自身尺寸的一半-->
4.2 translate()

如果想同時(shí)沿x軸和y軸移動(dòng),使用 translate()更方便。第一個(gè)值代表x軸,第二個(gè)值代表y軸。translate()translateX(),translateY()結(jié)合在一起的作用是一樣的。

translate(2em) 等于translate(2em,0) 等于 translateX(2em) 。

平移例子
4.3 translateZ()

translateZ()沿z軸平移元素,即在第三個(gè)維度中移動(dòng)元素。translateZ()只接受長度值。其實(shí)任何有關(guān)z軸的值都不可以使用百分?jǐn)?shù)。

4.4 translate3d()

translate3d()這個(gè)簡寫屬性能同時(shí)指定x軸,y軸,z軸的平移量。3D平移過程如下圖:

3D平移過程

圖中箭頭表示沿相應(yīng)軸的移動(dòng),最終達(dá)到3D空間中的一點(diǎn)。與translate()不同,如果translate3d()的值少于3個(gè),沒有假定的默認(rèn)值。因此類似translate3d(1em,-50px)操作是無效的,而不能假定為translate3d(1em,-50px,0)。

第五部分:縮放函數(shù) scale()

縮放變形可以把元素放大或縮小??s放函數(shù)的值都是無單位的實(shí)數(shù),而且始終為正數(shù)。在2D平面中,可以分別在x軸或者y軸上縮放,也可以同時(shí)在兩個(gè)軸上縮放。

函數(shù) 可取值
scaleX(),scaleY(),scaleZ() <number>
scale() <number>[,<number>]?
scale3d() <number>,<number>,<number>

提供給縮放函數(shù)的數(shù)字是個(gè)乘數(shù),因此,scaleX(2)將把元素的寬度變?yōu)樽冃吻暗膬杀?,?code>scaleY(0.5)將把元素的高度縮小一半。如果想在兩個(gè)軸上同時(shí)縮放,使用scale()。第一個(gè)值是x值,第二個(gè)是y值。因此scale(2,0.5)將把元素的寬度放大兩倍,將元素的高度縮小一半。如果只提供一個(gè)值,將用作兩個(gè)軸的縮放值。因此,scale(2)將把元素的寬度和高度都放大兩倍。這與translate()是不同的,在translate()中,省略的第二個(gè)值始終被設(shè)為0。下面圖片展示了使用scale()的例子:

image
image
5.1 三維空間縮放

能在二維空間縮放,也就能在三維空間縮放。css提供的scalez()函數(shù)僅在z軸上縮放,而scale3d()則能同時(shí)在三個(gè)軸上縮放。當(dāng)然,僅當(dāng)元素有深度時(shí),這兩個(gè)函數(shù)才有效果,而元素在默認(rèn)情況下沒有深度。如果讓元素有一定的深度,例如繞x軸或y軸旋轉(zhuǎn),那么深度就可以縮放。使用scalez()或者scale3d()都可以。

translate()一樣,scale3d()的三個(gè)數(shù)都必須是有效的。不然將導(dǎo)致所屬的整個(gè)變形值都失效。

第六部分:旋轉(zhuǎn)函數(shù) rotate()

旋轉(zhuǎn)函數(shù)繞某個(gè)旋轉(zhuǎn)軸元素,或者繞3D空間中的一個(gè)向量旋轉(zhuǎn)元素。旋轉(zhuǎn)變形有四個(gè)簡單的函數(shù),以及一個(gè)有些復(fù)雜,專門用于3D旋轉(zhuǎn)的函數(shù)。

函數(shù) 可取值
rotate(),rotateX(),rotateY(),rotateZ() <angle>

上面四個(gè)簡單的函數(shù)都只接受一個(gè)值:角度。角度以一個(gè)數(shù)字(可正可負(fù))和一個(gè)有效的角度單位(deg,grad,rad和turn)來表示。如果數(shù)字超出來相應(yīng)單位的常規(guī)范圍,將化為范圍內(nèi)的值。也就是說,437deg和77deg的效果是相同的,與-283deg的效果也是相同的。

但是僅當(dāng)沒有任何形式的動(dòng)畫,這樣的換算才算等效的。如果以動(dòng)畫的形式旋轉(zhuǎn)-20deg,元素稍微向左傾斜,而不轉(zhuǎn)動(dòng)。如果以動(dòng)畫的形式旋轉(zhuǎn)340deg,元素將向右轉(zhuǎn)動(dòng)幾乎一周。這兩次動(dòng)畫的最終狀態(tài)是一樣的,但是每次旋轉(zhuǎn)的過程是有差異的。

rotate()函數(shù)實(shí)施的是2D旋轉(zhuǎn),是我們最常用的旋轉(zhuǎn)方式。它的效果等同于rotateZ(),因?yàn)槎际抢@z軸旋轉(zhuǎn)(從顯示器射出來,直指你的眼睛)旋轉(zhuǎn)的。類似的,rotateX()繞x軸旋轉(zhuǎn),使元素向你傾斜或者遠(yuǎn)離你傾斜。rotateY()繞y軸旋轉(zhuǎn)元素,像門的開合一樣。如下圖效果:

image

上圖中有的例子涉及到3D效果。與后面章節(jié)的transform-styleperspective屬性配和才能達(dá)到的效果。這篇文章涉及的3D變形都是如此。如果只應(yīng)用現(xiàn)在提到的變形函數(shù)是得不到圖中所展示的效果的。

6.1 rotate3d()
函數(shù) 可取值
rotate3d() <number>,<number>,<number>,<angle>

如果你了解向量,可以把向量理解為坐標(biāo)空間中的箭頭。如下圖分別代表2維坐標(biāo)和3維坐標(biāo)的向量:

2維坐標(biāo)的向量
3D坐標(biāo)的向量

想在3D空間中旋轉(zhuǎn)元素,使用rotate3d()。前三個(gè)值指定3D空間中向量x,y和z的分量,第四個(gè)值是角度值,指定繞向量旋轉(zhuǎn)的量。

看個(gè)簡單的例子:rotate(45deg)用3D旋轉(zhuǎn)表示是 rotate3d(0,0,1,45deg)。這個(gè)向量在x軸和y軸上的大小是0,在z軸上的大小是1。也就是說,旋轉(zhuǎn)中心是z軸。元素將繞指定的向量旋轉(zhuǎn)45度。如下圖(包括繞x軸和y軸旋轉(zhuǎn)45度時(shí)應(yīng)該提供給rotate3d()的函數(shù)的值):

image

上圖中rotate(45deg)在3D空間中,等價(jià)于rotate3d(0,0,1,45deg)。前三個(gè)數(shù)設(shè)定向量的三個(gè)分量,這個(gè)向量在x軸和y軸上的大小為0。在z軸上的大小為1。因此,這個(gè)向量在z軸上,指向正方向,即指向觀察者。如果看向量的原點(diǎn),元素是順時(shí)針旋轉(zhuǎn)的。

類似的,rotateX(45deg)等價(jià)于rotate3d(1,0,0,45deg)。這個(gè)向量在x軸上,指向正方向(右方)。如果站在向量的的終點(diǎn)看向原點(diǎn),元素繞向量順時(shí)針旋轉(zhuǎn)45度,因此,站在常規(guī)的觀察者位置上,元素的頂部遠(yuǎn)離觀察者,元素的底部靠近觀察者。

假如說旋轉(zhuǎn)函數(shù)是rotate3d(-0.95,0.5,1,45deg)描述的向量。假設(shè)有個(gè)邊長200像素的立方體,那么這個(gè)向量在x軸上的大小為190像素,指向左方。在y軸上的大小為100像素,指向下方。在z軸上的大小為200像素,指向觀察者。這個(gè)向量從原點(diǎn)(0,0,0)指向(-190px,100px,200px)。如下圖:

image

這個(gè)向量就像一根金屬棒,穿過旋轉(zhuǎn)的元素。如果沿著向量向回看,元素順時(shí)針旋轉(zhuǎn)了45度。但是,由于向量指向左下前方,因此旋轉(zhuǎn)后的元素左上角靠近觀察著,而右下角遠(yuǎn)離觀察者。

rotate3d(1,1,0,45deg)rotateX(45deg) rotateY(45deg) rotateZ(0deg)不等效。

image

第七部分:傾斜函數(shù) skew()

函數(shù) 可取值
skewX(),skewY() <angle>
skew() <angle>,[,<angle>]?

傾斜函數(shù)沿x軸或y軸傾斜元素。元素不能沿z軸或3D空間中的向量傾斜。

skewX(),skewY()使元素傾斜指定的角度。如下圖:

image

skew(a,b)的效果是通過矩陣運(yùn)算實(shí)施2D傾斜的。下圖展示了幾個(gè)矩陣傾斜的例子。

image

第八部分:視域函數(shù) perspective()

image

在3D空間中改變?cè)氐男螒B(tài)時(shí),基本上都要賦予元素一定的視域。視域?yàn)樵刭x予前后深度,而這深度可以根據(jù)需要設(shè)定。

函數(shù) 可取值
perspective() <length>

設(shè)置較小的值得到較極端的視角,設(shè)置較大的值得到較溫和的視角。如下圖:

image

小于300px的視域值得到的效果特別失真,大于2000px的值失真“十分溫和”,而500px到1000px之前的值產(chǎn)生“適中的視域”。下圖展示了相同旋轉(zhuǎn)角度下不同視域值得到的結(jié)果。

image

視域值必須是正數(shù),而且不能為零。其他值都將導(dǎo)致 perspective()函數(shù)被忽略。 perspective()函數(shù)在變形函數(shù)列表中的位置十分重要。如果想在變形函數(shù)列表中設(shè)定視域值,一定要把 perspective()函數(shù)放在首位,只要也要放在以來視域的變形之前。

重要:transform函數(shù)的編寫順序十分重要。 perspective()函數(shù)與后面介紹的 perspective屬性十分相似,但是二者的用法完全不同。一般來說,最好使用 perspective屬性,不過也有需要使用 perspective()函數(shù)的例外情況。

第九部分:修改視域

視域其實(shí)由兩個(gè)屬性定義:一個(gè)定義視域?qū)傩跃嚯x,相當(dāng)于前面討論過的perspective()函數(shù)。另一個(gè)定義視域的原點(diǎn)。

9.1:定義視域 perspective 屬性

perspective 屬性的值是一個(gè)長度,定義視域錐體的深度。這么看來,它與前面討論的 perspective()函數(shù)類似,不過兩者之間有重要區(qū)別。

perspective
取值 `none <length>`
初始值 none
適用于 任何可變形的元素
計(jì)算值 絕對(duì)長度或者none
繼承性
動(dòng)畫性

如果想創(chuàng)建特別深的視域,仿照變焦鏡頭的效果,可以聲明perspective: 2500px。如果想讓深度淺一些,可以聲明perspective: 200px。

9.2: perspective 屬性與perspective()函數(shù)的區(qū)別
  • perspective()函數(shù)只為目標(biāo)元素定義視域,比如聲明perspective(800px) rotateY(45deg)。那么只有應(yīng)用這個(gè)規(guī)則的元素才能使用設(shè)定的視域。

  • perspective 屬性定義的視域深度應(yīng)用到目標(biāo)元素的所有子元素上。

這就是兩者的重要區(qū)別。perspective 屬性創(chuàng)建的3D空間為所有子元素共有,而perspective()函數(shù)只對(duì)目標(biāo)元素有效果,而且要放在變形函數(shù)列表的開頭或前面,多數(shù)時(shí)候,應(yīng)該使用perspective屬性。

9.3:移動(dòng)視域原點(diǎn) perspective-origin 屬性
perspective-origin
取值 ` [left center right top bottom <percentage> <length> ] [left center right top bottom <percentage> <length> ] && [left center right top bottom <percentage> <length> ]]<length>? `
初始值 50% 50%
適用于 任何可變形的元素
百分?jǐn)?shù) 相對(duì)范圍框計(jì)算
計(jì)算值 計(jì)算為一個(gè)百分?jǐn)?shù)。值為長度值時(shí),計(jì)算為絕對(duì)長度
繼承性
動(dòng)畫性 <percentage>,<length>

perspective-origin 定義視線匯聚于哪一點(diǎn)。

下圖表示不同視域原點(diǎn)下的“標(biāo)尺”(視域原點(diǎn)生效的前提是必須聲明perspective屬性):

image

第十部分:矩陣函數(shù) matrix()

matrix()
取值 <number>[,<number>]{5,5}

css變形規(guī)范對(duì)matrix()函數(shù)做了嚴(yán)格規(guī)定:以6個(gè)值a-f確定變換矩陣指定2D平面中的變形。

matrix()函數(shù)的有效值是6個(gè)以逗號(hào)分隔的數(shù)字。不能多,也不能少。數(shù)字可以為正或負(fù)。matrix()函數(shù)的值所用的句法十分復(fù)雜,描述的是元素變形后的最終狀態(tài),可以涵蓋其他所有變形類型(旋轉(zhuǎn),傾斜等)。最后,很少有人使用這個(gè)句法。

10.1 3D變形矩陣函數(shù)
matrix3d()
取值 <number>[,<number>]{15,15}

css變形規(guī)范對(duì)matrix3d()函數(shù)做了嚴(yán)格規(guī)定:以列主序排列一個(gè)4X4的齊次矩陣,用這個(gè)16個(gè)值指定3D變形。matrix3d()函數(shù)的值必須是16個(gè)以逗號(hào)分隔的數(shù)字,不能多也不能少。這些數(shù)字按列排列成一個(gè)4X4矩陣,第一列由第一組四個(gè)數(shù)構(gòu)成,第二列由第二組四個(gè)數(shù)構(gòu)成,以此類推。

本章只對(duì)矩陣函數(shù)進(jìn)行簡單介紹。

第十一部分:移動(dòng)原點(diǎn) transform-origin

目前所見的變形有個(gè)共同點(diǎn),都以元素的絕對(duì)中心為變形的原點(diǎn)。例如,旋轉(zhuǎn)元素時(shí),是繞著中心旋轉(zhuǎn)的,而不是繞著某一角度旋轉(zhuǎn)的。這是默認(rèn)行為,不過可以使用transform-origin屬性修改。

transform-origin
取值 ` [left center right top bottom <percentage> <length> ] [left center right top bottom <percentage> <length> ] && [left center right top bottom <percentage> <length> ]]<length>? `
初始值 50% 50%
適用于 任何可變形的元素
百分?jǐn)?shù) 相對(duì)范圍框計(jì)算
計(jì)算值 計(jì)算為一個(gè)百分?jǐn)?shù)。值為長度值時(shí),計(jì)算為絕對(duì)長度
繼承性
動(dòng)畫性 <percentage>,<length>

取值語法看似復(fù)雜,但是實(shí)際使用起來還是不難的。transform-origin屬性的值為兩個(gè)或三個(gè)關(guān)鍵字,用于定義相對(duì)哪個(gè)點(diǎn)變形。第一個(gè)值針對(duì)橫向,第二個(gè)值針對(duì)縱向,可選的第三個(gè)值是z軸上的長度。

橫軸和縱軸可以使用英語關(guān)鍵字,百分?jǐn)?shù),長度。而z軸不能使用英語關(guān)鍵字或百分?jǐn)?shù)。不過可以使用長度值。目前像素值是最常用的。

長度值設(shè)定的是距元素左上角的距離。所以,transform-origin: 5em 22px定義的變形原點(diǎn)距元素的左邊5em,距元素的頂邊22px。

百分?jǐn)?shù)相對(duì)對(duì)應(yīng)的軸和元素的尺寸計(jì)算。設(shè)定的是距元素左上角的偏移量。如:transform-origin: 67% 40%定義的元素距元素左邊的距離為寬度的67%,距元素頂邊的距離為高度的40%。如下圖:

image

加入我們把一個(gè)元素向右旋轉(zhuǎn)45度,通過設(shè)置變形原點(diǎn)的位置,那么元素的最終位置取決于變形原點(diǎn)。下圖展示了不同的變形原點(diǎn)得到的結(jié)果。

image

變形原點(diǎn)對(duì)其他變形類型也有影響,比如傾斜和縮放。如下圖:

image

有種變形不怎么受變形原點(diǎn)的影響——平移。使用translate()移動(dòng)元素,不管元素變形原點(diǎn)在哪,元素最終都被移動(dòng)到相同的位置。

第十二部分:變形方式 transform-style

如果在一個(gè)三維空間中改變?cè)氐男螒B(tài),例如使用translate3d(),或許希望在3D空間中呈現(xiàn)元素。然而,這不是默認(rèn)行為。默認(rèn)情況下,不管怎么變形,得到的結(jié)果都是扁平的。但是可以使用transform-style修改。

transform-style
取值 `flat preserve-3d`
初始值 flat
適用于 任何可變形的元素
計(jì)算值 指定的值
繼承性
動(dòng)畫性

假如我們想在適中的視域下移動(dòng)元素。使用下面css:

.inner {  
    transform: perspective(750px) translateZ(60px) rotateX(45deg); 
}
<div class="outer">
    <div class="inner">inner</div>
</div>

結(jié)果如下圖:

image

但是,如果向某一邊旋轉(zhuǎn)外層div,結(jié)果就與我們?cè)O(shè)想的不一樣了:內(nèi)層div像粘在外層div上的照片一樣,這與預(yù)期不符。因?yàn)?code>transform-style默認(rèn)值是flat。內(nèi)層div的上部前傾,下部后靠,像是緊貼在外層div上的圖像,隨外層一起旋轉(zhuǎn)。


.outer {  
    transform: perspective(750px) translateY(60px) rotateX(-20deg); 
}

.inner {  
    transform: perspective(750px) translateZ(60px) rotateX(45deg); 
}
<div class="outer">
    <div class="inner">inner</div>
</div>

結(jié)果如下圖:

image

然而,把值改成preserve-3d后,結(jié)果就截然不同了。內(nèi)層div繪制成一個(gè)3D對(duì)象,浮動(dòng)在外層div附近,因此也就不緊貼在外層div上了。


.outer {  
    transform: perspective(750px) translateY(60px) rotateX(-20deg); 
    transform-style: perserve-3d;
}

.inner {  
    transform: perspective(750px) translateZ(60px) rotateX(45deg); 
}
<div class="outer">
    <div class="inner">inner</div>
</div>

改動(dòng)后結(jié)果如下圖:

image
注意

transform-style設(shè)定的變形方式可能會(huì)被其他屬性覆蓋。這是因?yàn)槟切傩缘哪承┲狄笤丶捌渥釉乇仨氁员馄降姆绞匠尸F(xiàn)才能起作用。遇到這種情況,不管你把transform-style設(shè)為什么值,都會(huì)被強(qiáng)制重置為flat

為了避免被覆蓋,下面屬性要設(shè)為給出的值(這些也都是屬性的默認(rèn)值):

  • overflow: visible
  • filter: none
  • clip: auto
  • clip-path: none
  • mask-image: none
  • mask-border-source: none
  • mix-blend-mode: normal

如果突然發(fā)現(xiàn)3D變形效果無效,根源就可能存在上述列表中的某個(gè)屬性上。

第十三部分:處理背面 backface-visibility

在3D變形中,backface-visibility屬性可以看到元素的背面。

backface-visibility
取值 `visible hidden`
初始值 visible
適用于 任何可變形的元素
計(jì)算值 指定的值
繼承性
動(dòng)畫性

backface-visibility屬性決定元素的背面朝向我們時(shí)是否渲染背面,僅此而已。

假設(shè)翻轉(zhuǎn)兩個(gè)元素,一個(gè)元素的backface-visibility屬性設(shè)置為visible,另一個(gè)設(shè)置為hidden。

一個(gè)簡單的卡片翻轉(zhuǎn)效果演示 backface-visibility 的使用:

.card {
  position: relative;
  perspective: 800px;
  transform-style: preserve-3d;
  width:200px;
  height:280px;
  transition: all .6s;
  border: 1px solid #000;
  border-radius: 4px;
}

.card:hover {
  transform: rotateY(180deg);
}
img {
  position: absolute;
  width:100%;
  height: 100%;
  transition: all .5s;
  backface-visibility: hidden;
}
/*由于我們將兩個(gè)圖像都藏在了背面,所以另一面沒有任何東西。 所以接下來需要再把.front-face翻轉(zhuǎn)180度*/
.back-face {
  transform: rotateY(180deg);
}

<div class="card">
    <img class="front-face" src="1.jpg">
    <img class="back-face" src="2.jpg">
</div>

image

參考鏈接

鏈接如果打不開直接復(fù)制地址在瀏覽器打開

CSS權(quán)威指南(第四版)

從矩陣與空間操作的關(guān)系理解CSS3的transform

CSS 3D 旋轉(zhuǎn) rotate3d 與 translate3d

https://www.bilibili.com/video/av6731067/index_1.html?p=2

https://meyerweb.github.io/csstdg4figs/16-transforms/

https://htmldog.com/references/css/properties/transform/

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容