当我们使用CSS3 transform: operation1(...) operation2(...)
时,先完成哪一个?
第一个操作似乎是右侧中最多的一个。,即此operation2
在operation1
之前完成。 只是为了确定,这是真的吗?
注意:我在某些地方读过一件事,反之亦然(答案,互联网上的文章),这就是问题所在。
答案 0 :(得分:31)
是的,完成的第一个操作是右侧最多的操作。即operation2
operation1
之前完成。
以下是文档:http://www.w3.org/TR/css-transforms-1/但我还没有找到关于此的段落。
此处缩放完成首先,然后垂直翻译100px(如果先完成翻译,缩放将使500px的翻译!)
#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>
&#13;
此处翻译完成首先,然后缩放(在之后完成缩放使翻译看起来像500px翻译!)
#container {
position: absolute;
transform: scale(5) translate(0,100px);
transform-origin: 0 0; }
&#13;
<div id="container"><img src="https://i.stack.imgur.com/xb47Y.jpg"></img></div>
&#13;
答案 1 :(得分:3)
转换执行从左到右。变换对应于矩阵运算,这些运算从左到右执行。
背后有直觉,不仅仅是这在规范中作为规范性规则(第3点:https://drafts.csswg.org/css-transforms-1/#transform-rendering)
这是一支可以尝试的笔:https://codepen.io/monfera/pen/YLWGrM
说明:
每个变换步骤都建立自己的坐标系。所以
transform: translateX(500px);
沿其父级的X轴建立一个新的坐标系500px,该元素将在那里渲染。
类似地,
background-color: blue;
transform: translateX(500px) rotate(60deg);
首先沿着其父级的X轴(右侧)建立一个新的坐标系500px,然后只建立,在其内部(已翻译,但它现在不相关)坐标系它是否执行旋转。所以它是一个向右旋转500px的形状,然后旋转到位(在所谓的transform-origin
周围,在本地坐标系中解释,默认为50%50%对于旋转意味着,围绕矩形的中心旋转,但它是旁边的。)
相反的顺序
background-color: orange;
transform: rotate(60deg) translateX(500px);
首先建立一个相对于父级旋转60度的新坐标系,然后沿着现在旋转的坐标系的X轴平移100px,方向不是实际上从文档(或用户)的全局角度来看是正确的。所以,在这种情况下,就像你先旋转纸张一样,然后沿纸张侧面(从原点,在这种情况下是左上角)滑动500个单位的形状。
要进行更高级的讨论,并了解如何直观地理解这两个方向,请查看Composing Transformations - CSS变换遵循后乘法模型,因此请查找包含标题&#34;将转换视为转换局部坐标系&#34; (插图似乎有点偏离)
答案 2 :(得分:0)
我刚刚使用 CSS 转换在 HTML 中创建了一个 3d 房间的演示。我为后墙制作了一个 200x200 DIV,将它留在那个位置。然后我从相同的大小和位置开始做了一个左墙,然后添加
变换:translate3d(-100px,0px,100px)rotateY(90deg)。
然后我做了一个右墙并添加
变换:translate3d(100px,0px,100px)rotateY(90deg)。
这正确地创建了房间。但这是 Safari 13 版。本来我试着先列出旋转步骤,但墙在一个奇怪的位置。所以我看到了从右到左的行为。
答案 3 :(得分:-1)
在其他答案和评论中已经提到了这一点,但我认为没有足够强调:简短的答案是两种方法都是有效的。
这完全取决于您是否考虑将坐标附加到元素上(从左到右)还是根据初始元素位置(从右到左)固定到页面上。
这里有一篇文章展示了动画的区别(这使它更容易理解):Chaining transforms。
以下是显示文章动画的摘录:
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>
实际的实现方式与从左到右还是从右到左无关紧要,只要您牢记差异,两者在创建动画时都同样有效。