解放生產(chǎn)力!Transform 支持單獨(dú)賦值改變
在 Chrome 104 中,支持了一個(gè)非常有意思的新特性。CSS 中的 ??transform?
? 支持單獨(dú)賦值改變。不要小看這一點(diǎn),此點(diǎn)改動(dòng)在很多時(shí)候,能夠非常有效的解放生產(chǎn)力,算是一個(gè)非常 NICE 的更新。
淺析一下
什么意思呢?我們來看這樣一個(gè)例子:
在之前,我們可以利用 transform 配合絕對(duì)定位的 top、left 進(jìn)行任意元素的水平垂直居中,像是這樣:
<div></div>
div {
width: 200px;
height: 200px;
background: #000;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
這樣,我們就得到了一個(gè)水平垂直居中的元素:
但是,如果我們想對(duì)這個(gè)元素進(jìn)行一個(gè)縮放的動(dòng)畫,該怎么做呢?會(huì)是這樣:
div {
width: 200px;
height: 200px;
background: #000;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
@keyframes scale {
0% {
transform: translate(-50%, -50%) scale(1);
}
100% {
transform: translate(-50%, -50%) scale(1.2);
}
}
好的,動(dòng)畫本身,并不是重點(diǎn)。重點(diǎn)在于,在上述的 @keyframes 代碼中,我們想改變的其實(shí)只有 scale()? 的值,但是基于現(xiàn)有的 CSS 機(jī)制,我們必須把前面控制定位的 ?translate()? 一并寫上。
transform 拆開書寫
為了解決這個(gè)痛點(diǎn),規(guī)范支持了將 transform 分開書寫的方式。
所以,對(duì)于這一句,transform: translate(-50%, -50%) scale(1),我們可以分別拆開成 translate 和 scale:
div {
width: 200px;
height: 200px;
background: #000;
position: absolute;
top: 50%;
left: 50%;
// transform: translate(-50%, -50%); 刪掉這句
translate: -50% -50%;
scale: 1;
animation: scale 1s infinite linear alternate;
}
@keyframes scale {
0% {
scale: 1;
}
100% {
scale: 1.2
}
}
是的,我們可以通過 translate? 和 scale? 分開控制它們,這樣我們就能愉快的在 @keyframes? 中,只進(jìn)行 scale 的動(dòng)畫了!妙哉。
所以,根據(jù)規(guī)范 -- [1],于 transform 而言,我們可以將它整個(gè)拆解為:
- translate
- rotate
- scale
具體的語(yǔ)法會(huì)有一點(diǎn)點(diǎn)不同,具體使用的時(shí)候,多看看文檔,譬如 translate 接收 3 個(gè)參數(shù),第 2、3 個(gè)參數(shù)如果不存在,則為零(例如:translate: 50% 50% 0)。又譬如 rotate,如果想改變 Y 軸的旋轉(zhuǎn)角度,可以這樣寫 rotate: y 30deg。
再舉個(gè)例子,下面兩組代碼是等效的:
// 上下兩組代碼產(chǎn)生的效果等效!
{
transform: translate(-50%, -50%) rotateZ(30deg) scale(1.2);
}
{
translate: -50% -50%;
rotate: Z 30deg;
scale: 1.2;
}
是的,比較奇怪的是,規(guī)范里沒有涉及到 skew 的拆解。
順序?qū)?transform 的影響
當(dāng)然。拆開后和原本寫在一起并非完全一樣。
如果,我們使用的是 transform,將它們?nèi)繉懺谝黄穑袷沁@樣:
div {
transform: rotateY(90deg) translateZ(400px) scale(1.2);
}
此時(shí),元素的 transform 變換遵循的是從左向右進(jìn)行變換。也就是先旋轉(zhuǎn) ??rotate?
??,再 ??translateZ()?
??,最后縮放 ??scale()?
?。
但是如果,我們分開來寫:
div {
rotate: Y 90deg;
translate: 0 0 400px;
scale: 1.2;
}
雖然代碼屬性的順序是 rotate --> translate --> scale,但是實(shí)際上,無論他們的書寫順序如何,解析的時(shí)候都會(huì)按照首先 translate,然后 rotate,最后 scale 的順序進(jìn)行!
這個(gè)會(huì)有什么影響嗎?當(dāng)然,這里我們來看這樣一個(gè)例子。假設(shè),我們想實(shí)現(xiàn)這樣一個(gè)立方體:
不算上下兩個(gè)面,以其余 4 個(gè)面為例子,正常的做法是,在 transform-style: preserve-3d 狀態(tài)下,每個(gè)面先繞 Y 軸旋轉(zhuǎn)一定的角度,然后進(jìn)行 translateZ() 的位移。
像是這樣:
所以,代碼會(huì)是這樣:
face1 {
transform: rotateY(0) translateZ(200px);
}
face2 {
transform: rotateY(90deg) translateZ(200px);
}
face3 {
transform: rotateY(180deg) translateZ(200px);
}
face4 {
transform: rotateY(270deg) translateZ(200px);
}
注意,這里 transform 的變換是先旋轉(zhuǎn),再位移。
如果我們拆開寫,變成:
face2 {
rotate: Y 90deg;
translate: 0 0 200px;
}
//...
則整個(gè)效果就變成了:
因?yàn)檫@里實(shí)際執(zhí)行的順序是,先 translate,后 rotate。
所以,實(shí)際使用的時(shí)候一定要注意,矩陣變換的順序會(huì)影響最終的效果。如果對(duì)順序有嚴(yán)格的要求,還是需要合在一起寫。
總結(jié)一下
本文比較簡(jiǎn)單,沒有復(fù)雜的 CSS 動(dòng)效,主要介紹了從 Chrome 104 開始,transform 支持單獨(dú)賦值這一更新。其中有三點(diǎn)需要注意:
- 于transform 而言,我們可以將它整個(gè)拆解為 translate、rotate、scale 的分開寫法。
- 對(duì)于完整的transform 而言,其執(zhí)行順序遵循從左向右進(jìn)行變換。
- 對(duì)于分開寫的transform 而言,無論其書寫順序,總是按照先 translate,然后 rotate,最后 scale 的順序進(jìn)行!
最后
好了,本文到此結(jié)束,希望本文對(duì)你有所幫助 :)
參考資料
[1]W3 - individual-transforms: ?https://www.w3.org/TR/css-transforms-2/#individual-transforms?。
[2]CodePen Demo -- 3D Box View: https://codepen.io/Chokcoco/pen/vYjpWBW?editors=0100?。
[3]Github -- iCSS: https://github.com/chokcoco/iCSS?。