當我們使用CSS3 transform: operation1(...)操作2(...),先做哪個?
完成的第一個操作似乎是最右邊的一個。,即這里工序2在工序1之前完成。只是確定一下,是真的嗎?
注:我在某些地方(答案,網上的文章)看過一件事和它相反的,所以才有了這里的問題。
是的,完成的第一個操作是最右邊的一個。,即這里工序2在工序1之前完成。
這篇MDN文章確實指出:
變換函數(shù)按從左到右的順序相乘,這意味著復合變換是按從右到左的順序有效應用的。
這是文件:http://www.w3.org/TR/css-transforms-1/.
示例1 這里先進行縮放,然后垂直平移100像素(如果先平移,縮放將平移500像素!)
#container {
position: absolute;
transform: translate(0,100px) scale(5);
transform-origin: 0 0; }
<div id="container"><img src="https://i.stack.imgur.com/xb47Y.jpg"></img></div>
這一點在其他回答和評論中已經提到過,但在我看來還不夠強調:簡單的回答是兩種方式都有效。
這完全取決于您是將坐標附加到元素上(從左到右)還是基于元素的初始位置固定到頁面上(從右到左)。
這里有一篇文章展示了與動畫的區(qū)別(這更容易理解):鏈接變換。
下面是一個片段,展示了文章中的動畫:
html, body { height: 100%; }
body {
background: #aaa;
color: #000;
font-family: Calibri,Candara,Segoe,"Segoe UI",Optima,Arial,sans-serif;
overflow: hidden;
margin: 0;
}
.info {
text-align: center;
font-family: Consolas,monaco,monospace;
font-size: 20px;
font-weight: bold;
margin-bottom: 4px;
color: #fff;
}
.split { white-space: nowrap; }
.side {
display: inline-block;
width: 50%;
}
.label {
text-align: center;
font-size: 20px;
}
.container {
position: relative;
font-size: 50px;
margin: .6em auto 0;
width: 0; height: 0;
transform: translateX(-1em);
}
.ltr .object {
position: absolute;
left: 0; top: 0;
width: 1em; height: 1em;
margin: -.5em 0 0 -.5em;
background: rgb(114,34,34);
animation: ltrObj 5s infinite;
}
@keyframes ltrObj {
from, 10% { transform: rotate( 0deg) translateX(0em); }
40% { transform: rotate(45deg) translateX(0em); }
70%, to { transform: rotate(45deg) translateX(2em); }
}
.object.shadow {
animation: none;
opacity: .2;
}
.ltr .axes {
position: absolute;
left: .5em; top: .5em;
width: 1em; height: 1em;
color: #111;
box-sizing: border-box;
border-left: 2px solid;
border-top: 2px solid;
}
.ltr .axes::before, .ltr .axes::after {
content: '';
position: absolute;
width: .2em; height: .2em;
box-sizing: border-box;
border-left: 2px solid;
border-top: 2px solid;
transform-origin: top left;
}
.ltr .axes::before { top: 100%; left: 0; margin-left: -1px; margin-top: 1px; transform: rotate(225deg); }
.ltr .axes::after { top: 0; left: 100%; margin-top: -1px; margin-left: 1px; transform: rotate(135deg); }
.rtl .axes {
position: absolute;
left: 0; top: 0;
width: 2.5em; height: 2.3em;
color: #111;
box-sizing: border-box;
border-left: 2px solid;
border-top: 2px solid;
}
.rtl .axes::before, .rtl .axes::after {
content: '';
position: absolute;
width: .2em; height: .2em;
box-sizing: border-box;
border-left: 2px solid;
border-top: 2px solid;
transform-origin: top left;
}
.rtl .axes::before { top: 100%; left: 0; margin-left: -1px; margin-top: 1px; transform: rotate(225deg); }
.rtl .axes::after { top: 0; left: 100%; margin-top: -1px; margin-left: 1px; transform: rotate(135deg); }
.rtl .object {
position: absolute;
left: 0; top: 0;
width: 1em; height: 1em;
margin: -.5em 0 0 -.5em;
background: rgba(100,0,0,0.8);
animation: rtlObj 5s infinite;
}
@keyframes rtlObj {
from, 10% { transform: rotate( 0deg) translateX(0em); }
40% { transform: rotate( 0deg) translateX(2em); }
70%, to { transform: rotate(45deg) translateX(2em); }
}
.helper-mask {
position: absolute;
left: 0; top: 0;
width: 3em; height: 3em;
overflow: hidden;
}
.helper {
position: absolute;
left: 0; top: -2em;
width: 0; height: 2em;
margin-top: 2px;
box-sizing: border-box;
border: 2px solid #00c;
border-left: none;
border-radius: 0 100% 0 0;
transform-origin: bottom left;
animation: helper 5s infinite;
}
@keyframes helper {
from, 10% { width: 0em; transform: rotate( 0deg); }
40% { width: 2em; transform: rotate( 0deg);}
70%, to { width: 2em; transform: rotate(45deg);}
}
<div class="info">rotate(45deg) translateX(2em)</div>
<div class="split">
<div class="side ltr">
<div class="label">Left to Right</div>
<div class="container">
<div class="object shadow"></div>
<div class="object">
<div class="axes"></div>
</div>
</div>
</div>
<div class="side rtl">
<div class="label">Right to Left</div>
<div class="container">
<div class="axes"></div>
<div class="object"></div>
<div class="helper-mask">
<div class="helper"></div>
</div>
</div>
</div>
</div>
從左到右執(zhí)行變換。變換對應于矩陣運算,并且是從左到右執(zhí)行的。
這背后有直覺,而不僅僅是規(guī)范中字面上的規(guī)范性規(guī)則(這里的第三點:https://drafts . csswg . org/CSS-transforms-1/# transform-rendering)
這里有一支筆可以試試:https://codepen.io/monfera/pen/YLWGrM
解釋:
每個變換步驟都建立自己的坐標系。因此
transform: translateX(500px);
沿著其父元素的X軸建立一個新的坐標系500px,元素將在此處呈現(xiàn)。
同樣的,
background-color: blue;
transform: translateX(500px) rotate(60deg);
首先沿其父對象的X軸(向右)建立一個新的坐標系500px,然后,僅在該坐標系(已轉換,但現(xiàn)在不相關)內執(zhí)行旋轉。因此,它將是一個向右旋轉500像素的形狀,并在適當?shù)奈恢眯D(圍繞所謂的變換原點,這在本地坐標系中進行解釋,旋轉的默認50% 50%意味著圍繞矩形的中心旋轉,但這是一個旁注)。
相反的順序
background-color: orange;
transform: rotate(60deg) translateX(500px);
首先建立一個相對于父坐標系旋轉了60度的新坐標系,然后沿著現(xiàn)在旋轉的坐標系的X軸平移100像素,從文檔(或用戶)的全局視點來看,這個方向實際上并不向右。因此,在這種情況下,就好像您首先旋轉紙張,然后沿著紙張的邊(從原點,在這種情況下是左上角)將形狀滑動500個單位。
要進行更深入的討論,并了解如何直觀地理解兩個方向,請查看合成轉換——CSS轉換遵循后乘法模型,因此請查找標題為“將轉換視為轉換局部坐標框架”的頁面(盡管插圖似乎有點偏離主題)
它首先應用最左邊的變換。
正如你在上面的圖片中看到的,第一個轉換比第二個轉換需要更長的距離。原因是第一個示例首先進行縮放,然后根據(jù)x軸上的新寬度采用translate指定的距離。因為現(xiàn)在更寬了,50%會導致它走的距離更長。由50%指定的度量是通過取其自身寬度的一半來計算的。
我引用的網站
我剛剛用CSS轉換創(chuàng)建了一個HTML格式的3d房間演示。我為后墻制作了一個200x200的DIV,并將其保留在該位置。然后我做了一面左墻,從同樣的尺寸和位置開始,然后添加
transform: translate3d(-100px,0px,100px)rotateY(90度)。
然后我做了一個右墻,加上
transform: translate3d( 100px,0px,100px) rotateY(90deg)。
這正確地創(chuàng)建了房間。但這是用Safari的13版。最初我試圖先列出旋轉步驟,但墻在一個奇怪的位置。所以我看到的是從右向左的行為。