当我们使用CSS3 transform: operation1(...) operation2(...)时,首先执行哪一个?
transform: operation1(...) operation2(...)
第一个操作似乎是最 * 在右边的一个。这里operation2在operation1之前完成。”””只是为了确定,这是真的吗?**
operation2
operation1
3z6pesqy1#
是的,第一个操作是右边最大的操作,即。这里operation2在operation1之前完成。这个MDN article确实声明:变换函数按从左到右的顺序相乘,这意味着 * 复合变换按从右到左的顺序有效地应用 *。以下是文档:http://www.w3.org/TR/css-transforms-1/。
在这里,缩放是 * 首先 * 完成的,* 然后 * 垂直平移100 px(如果先进行平移,缩放将平移500 px!)
#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>
这里的翻译是 * 第一 , 然后 * 缩放(缩放 * 后 * 做的翻译看起来像500 px的翻译!)
#container { position: absolute; transform: scale(5) translate(0,100px); transform-origin: 0 0; }
uttx8gqw2#
这一点在其他回答和评论中已经提到,但在我看来没有得到足够的强调:简单的答案是两种方式都有效。这完全取决于您是否考虑到您的坐标附加到您的元素(从左到右),还是基于初始元素位置(从右到左)固定到页面。这里有一篇文章展示了动画的区别(这使得它更容易理解):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>
实际的实现是使用从左到右还是从右到左是无关紧要的,在创建动画时两者都是同样有效的,只要记住区别。
iq0todco3#
转换执行从左到右。变换对应于矩阵运算,并且这些从左到右执行。它背后有直觉,这不仅仅是规范中的规范规则(这里的第3点:https://drafts.csswg.org/css-transforms-1/#transform-rendering)这里有一支笔可以试试:https://codepen.io/monfera/pen/YLWGrM说明:每个变换步骤都建立自己的坐标系。所以呢
transform: translateX(500px);
沿着其父元素的X轴建立一个新的坐标系500 px,元素将在那里呈现。同样地,
background-color: blue; transform: translateX(500px) rotate(60deg);
首先沿着父对象的X轴(向右)建立一个新的坐标系500 px,然后 * 才在该坐标系(已平移,但现在不相关)内执行旋转。因此,它将是一个向右500 px的形状,并在适当的位置旋转(围绕所谓的transform-origin,在局部坐标系中解释,默认的50% 50%旋转意味着围绕矩形中心旋转,但这是一个旁白)。相反的顺序
transform-origin
background-color: orange; transform: rotate(60deg) translateX(500px);
首先建立一个相对于父级旋转60度的新坐标系,* 然后 * 沿着现在旋转的坐标系的X轴平移100 px,方向实际上不是从文档(或用户)的全局视点向右。因此,在这种情况下,就像您首先旋转纸张,然后沿着纸张的侧面(从原点,在这种情况下是左上角)滑动形状500个单位。
对于更高级的讨论,以及如何直观地理解它的两个方向,请查看Composing Transformations- CSS转换遵循后乘法模型,因此请查找标题为“将转换视为转换局部坐标框架”的页面(插图似乎有点偏离)
xxls0lw84#
它首先应用最左边的变换。
如上图所示,与第二个变换相比,第一个变换需要更长的距离。原因是第一个示例首先经历scale,然后根据x轴上的新宽度采用translate指定的距离。因为它现在更宽了,50%将导致它需要更长的距离。由50%指定的测量值是通过取其自身宽度的一半来计算的。the site I cited from
scale
translate
50%
xtfmy6hx5#
我刚刚使用CSS转换在HTML中创建了一个3D房间的演示。我做了一个200 x200 DIV的后墙,离开它在那个位置。然后我做了一个左墙开始在相同的大小和位置,然后添加transform:translate3d(-100px,0px,100px)rotateY(90deg).然后我做了一个右墙,并添加transform:translate3d(100px,0px,100px)rotateY(90deg).这样就正确地创建了房间。但这是在Safari 13版本中。最初我试图先列出旋转步骤,但墙的位置很奇怪。所以我看到了从右到左的行为。
5条答案
按热度按时间3z6pesqy1#
是的,第一个操作是右边最大的操作,即。这里
operation2
在operation1
之前完成。这个MDN article确实声明:
变换函数按从左到右的顺序相乘,这意味着 * 复合变换按从右到左的顺序有效地应用 *。
以下是文档:http://www.w3.org/TR/css-transforms-1/。
示例1
在这里,缩放是 * 首先 * 完成的,* 然后 * 垂直平移100 px(如果先进行平移,缩放将平移500 px!)
示例二
这里的翻译是 * 第一 , 然后 * 缩放(缩放 * 后 * 做的翻译看起来像500 px的翻译!)
uttx8gqw2#
这一点在其他回答和评论中已经提到,但在我看来没有得到足够的强调:简单的答案是两种方式都有效。
这完全取决于您是否考虑到您的坐标附加到您的元素(从左到右),还是基于初始元素位置(从右到左)固定到页面。
这里有一篇文章展示了动画的区别(这使得它更容易理解):Chaining transforms。
下面是一个片段,显示了文章中的动画:
实际的实现是使用从左到右还是从右到左是无关紧要的,在创建动画时两者都是同样有效的,只要记住区别。
iq0todco3#
转换执行从左到右。变换对应于矩阵运算,并且这些从左到右执行。
它背后有直觉,这不仅仅是规范中的规范规则(这里的第3点:https://drafts.csswg.org/css-transforms-1/#transform-rendering)
这里有一支笔可以试试:https://codepen.io/monfera/pen/YLWGrM
说明:
每个变换步骤都建立自己的坐标系。所以呢
沿着其父元素的X轴建立一个新的坐标系500 px,元素将在那里呈现。
同样地,
首先沿着父对象的X轴(向右)建立一个新的坐标系500 px,然后 * 才在该坐标系(已平移,但现在不相关)内执行旋转。因此,它将是一个向右500 px的形状,并在适当的位置旋转(围绕所谓的
transform-origin
,在局部坐标系中解释,默认的50% 50%旋转意味着围绕矩形中心旋转,但这是一个旁白)。相反的顺序
首先建立一个相对于父级旋转60度的新坐标系,* 然后 * 沿着现在旋转的坐标系的X轴平移100 px,方向实际上不是从文档(或用户)的全局视点向右。因此,在这种情况下,就像您首先旋转纸张,然后沿着纸张的侧面(从原点,在这种情况下是左上角)滑动形状500个单位。
对于更高级的讨论,以及如何直观地理解它的两个方向,请查看Composing Transformations- CSS转换遵循后乘法模型,因此请查找标题为“将转换视为转换局部坐标框架”的页面(插图似乎有点偏离)
xxls0lw84#
它首先应用最左边的变换。
如上图所示,与第二个变换相比,第一个变换需要更长的距离。原因是第一个示例首先经历
scale
,然后根据x轴上的新宽度采用translate
指定的距离。因为它现在更宽了,50%
将导致它需要更长的距离。由50%
指定的测量值是通过取其自身宽度的一半来计算的。the site I cited from
xtfmy6hx5#
我刚刚使用CSS转换在HTML中创建了一个3D房间的演示。我做了一个200 x200 DIV的后墙,离开它在那个位置。然后我做了一个左墙开始在相同的大小和位置,然后添加
transform:translate3d(-100px,0px,100px)rotateY(90deg).
然后我做了一个右墙,并添加
transform:translate3d(100px,0px,100px)rotateY(90deg).
这样就正确地创建了房间。但这是在Safari 13版本中。最初我试图先列出旋转步骤,但墙的位置很奇怪。所以我看到了从右到左的行为。