CSS - 變形

變形 - transform

transform(變形)、translate(平移)、transition(轉場) 是剛學習 CSS 常搞混的三個名詞,transform 是改變盒子的形狀與行為,translate 是 transform 的其中一個函式,而 transition 指的是樣式屬性兩種狀態的變化。變形(transform)的出現在於早期網頁設計只有四四方方的矩形所組合成版型,而隨著人們的想法,開始有人覺得如果不再是矩形呢?有了想打破這矩形的限制,transform 就這樣誕生了。

變形有四個函式,分別是平移(translate)、縮放(scale)、旋轉(rotate)、歪斜(skew)。

座標系統

CSS 世界使用的座標系統是「笛卡爾座標系統」,沒錯,就是那位「我思,故我在」的笛卡爾。X 軸跟我們認知是一樣,往右為正值,往左為負值;但有點不同的是,一般我們的認知是 Y 軸 的正值應該是往上,但是對於 CSS 而言,不管是定位(position)、變形(transform)又或是使用文字陰影(text-shadow)、盒陰影(box-shadow), Y 的正值是相反,也就是往下。而最後的 Z 軸,就如同定位的 z-index,朝著使用者是數值是越大,遠離使用者為數值越小。

X 軸(右正、左負),Y 軸(下正、上負),Z 軸(朝向使用者數值越大、遠離使用者數值越小)

球面系統

其次,CSS 變形中旋轉(rotate)使用的是球面系統(spherical system)。可以想成每個軸位方向如同一根棍子插入球體時,此時球體可以轉動的方向。

X 軸(前後翻轉)、Y 軸(左右翻轉)、Z 軸(平面旋轉)

重要規則

變形可以套用多個函式,寫法是之間不需要逗點分隔。變形函式的順序會由左至右套用,順序很重要,它會影響整個變形的結果。例如先旋轉再做平移,會往旋轉後的角度平移;而先平移再選轉,則是平移後再做旋轉。變形只要任何一個函式不符合語法,就會導致整個變形錯誤被忽略。另外,變形無法對任何行內盒(inline box),必須作用在 block、inline-block、flex-item、grid-item 這些等級盒子上。最後,變形是不會疊加,重寫變形只會讓後方覆寫前方效果,以最後一次變形為主。但這規則卻有個例外,那就是遇到轉場(transition)或動畫(animation),會疊加轉換的效果。

平移 - translate

平移可以接受絕對數值或百分比(除了 Z 軸),只有 X、Y 軸接受百分比的設定,它會依據該盒子 width、height 的值為依據,進行百分比的計算。3D 版的 translate 必須要有三個數值

.translate {
/* 可以設定 X、Y 2D 平移 */
transform: translate(50px, 100px);
/* 可以設定單軸 X 平移 */
transform: translateX(50px);
/* 可以設定單軸 Y 平移 */
transform: translateY(100px);
/* 也有 3D 版,一定要設定三個數值 */
transform: translate3d(100px, 100px, 100px);
}

縮放 - scale

顧名思義,「縮」就是縮放的縮,「放」就是縮放的放,倍數縮放元素的寬、高。3D 版的 scale 必須要有三個數值

.scale {
/* 數值是以倍數顯示 */
transform: scale(2);
/* 若是負數會呈現倒影型態 */
transform: scale(-2);
/* 可以設定單軸 X 縮放 */
transform: scaleX(2);
/* 可以設定單軸 Y 縮放 */
transform: scaleY(2);

/* 改變原點 */
/* 預設值為 50% 50%,就是在 box 中心點。如果省略第 2 個值,會視為 center (50%) */
/* 數值可以是單位 em、px、%、left、right、top、bottom;center */
transform-origin: center center;
/* scale3d()設定數值跟 translate3d 一樣要 3 個數值 */
transform: scale3d(1, 2, 3);
}

旋轉 - rotate

旋轉函式涉及到 3D,是所有變形函式中最不容易理解的函式,因為它並須搭配球體系統以及 trasform-style(選擇 3D 樣式) 與 perspective(透視)。

.rotate {
width: 300px;
height: 300px;
/* 記得要加單位 deg,正為順時針,負為逆時針 */
/* 可以搭配 transform-style、perspective 屬性作到翻轉透視的效果。 */
transform: rotate(45deg);
transform: rotateX(45deg);
transform: rotateY(45deg);
transform: rotateZ(45deg);
/* rotate3D(1, 1, 0, 45deg) 不等於 rotateX(45deg)、rotateY(45deg)、rotateZ(0deg) */
/* 其實是 rotate3d(300px,300px,300px,45deg),指旋轉的中心軸會從原點指向右方300px、下方300px,旋轉 45deg */
transform: rotate3D(1, 1, 0, 45deg);
transform-origin: center center;
}

歪斜 - skew

.skew {
/* 記得要加單位 deg */
/* 第一個數值為 X 的歪斜角,第二個數值為 Y 的歪斜角 */
transform: skew(45deg, 0deg);
transform: skewX(45deg);
transform: skewY(45deg);
transform-origin: center center;
}

原點 transform-origin

變形大部分的屬性都會有一個原點去支撐該屬性變化的依據,例如旋轉時,原點的初始值為 50%,50%。也就是正中央的位置,因此我們會看到旋轉式依據中心點去做旋轉,我們也可以使用 transform-origin 這個屬性改變原點的位置,讓變形擁有更多變化性。它由水平方向、垂直方向兩個值組成,預設為 50%,50%(center,center),也可以使用關鍵字 left、right、center、bottom、top 去組合,若是以百分比則是以元素尺寸的基準去計算。最後注意的是,translate(平移)沒有所謂的原點

.transform-origin {
/* 改變原點 */
/* 預設值為 50% 50%,就是在 box 中心點。如果省略第 2 個值,會視為 center (50%) */
/* 數值可以是單位 em、px、%、left、right、top、bottom;center */
transform-origin: center center;
}