CSS 如果在 属性 末尾设置透视,则 3d 变换不起作用
CSS 3d transform doesn't work if perspective is set in the end of property
我发现 transform
属性 取决于 perspective()
位置
为什么会这样? transform
的任何其他 rules/limitations?
虽然我觉得很奇怪,但这似乎不是一个错误,因为我能够在 Chrome/FF
中重现它
box:nth-child(1):hover {
transform: perspective(1000px) translate3d(0, 0, -100px);
}
box:nth-child(2):hover {
transform: translate3d(0, 0, 100px) perspective(1000px);
}
box {
padding: 20px;
display: inline-flex;
align-items: center;
justify-content: center;
font-family: monospace;
transition: transform .4s;
background: rgba(255, 0, 0, 0.3);
margin: 20px;
font-size: 12px;
perspective: 1000px;
cursor: pointer;
}
box:nth-child(2) {
background: rgba(0, 0, 255, 0.3);
}
<box>
transform: perspective(1000px) translate3d(0,0,100px);
</box>
<box>
transform: translate3d(0,0,100px) perspective(1000px);
</box>
在这两种情况下,您都应该将 perspective
放在首位。如果加在最后会先翻译,不考虑视角
如果我们参考 specification 我们可以看到转换矩阵是如何计算的:
The transformation matrix is computed from the transform and
transform-origin properties as follows:
Start with the identity matrix.
Translate by the computed X and Y of transform-origin
Multiply by each of the transform functions in transform property from
left to right
Translate by the negated computed X and Y values of transform-origin
正如您在步骤 (3) 中看到的那样,它是从 左到右 (这是另一个问题,您可以在其中获得更多信息并了解顺序的重要性:)
在要变换的元素中使用perspective属性也没用。
box:nth-child(1):hover {
transform: perspective(1000px) translate3d(0, 0, -100px);
}
box:nth-child(2):hover {
transform: perspective(1000px) translate3d(0, 0, 100px);
}
box {
padding: 20px;
display: inline-flex;
align-items: center;
justify-content: center;
font-family: monospace;
transition: transform .4s;
background: rgba(255, 0, 0, 0.3);
margin: 20px;
/*perspective: 1000px;*/
font-size: 12px;
cursor: pointer;
}
box:nth-child(2) {
background: rgba(0, 0, 255, 0.3);
}
<box>
transform: perspective(1000px) translate3d(0,0,100px);
</box>
<box>
transform: perspective(1000px) translate3d(0,0,100px);
</box>
为避免与顺序混淆,您可以在父元素中声明透视图,但您需要注意原点,因为它不会相同:
box:nth-child(1):hover {
transform:translate3d(0, 0, -100px);
}
box:nth-child(2):hover {
transform:translate3d(0, 0, 100px);
}
body {
perspective:1000px;
}
box {
padding: 20px;
display: inline-flex;
align-items: center;
justify-content: center;
font-family: monospace;
transition: transform .4s;
background: rgba(255, 0, 0, 0.3);
margin: 20px;
font-size: 12px;
cursor: pointer;
}
box:nth-child(2) {
background: rgba(0, 0, 255, 0.3);
}
<box>
transform: perspective(1000px) translate3d(0,0,100px);
</box>
<box>
transform: perspective(1000px) translate3d(0,0,100px);
</box>
虽然另一个答案已经非常清楚地说明了 perspective()
是如何工作的。但我想让我更具体一点。
box:nth-child(1):hover {
transform: perspective(1000px) translate3d(0, 0, 100px);
}
box:nth-child(2):hover {
transform: translate3d(0, 0, 100px) perspective(1000px);
}
box:nth-child(3):hover {
transform: rotate3d(1, 0, 0, 45deg) perspective(1000px) translate3d(0, 0, 100px);
}
box:nth-child(4):hover {
transform: rotate3d(1, 0, 0, 45deg) translate3d(0, 0, 100px) perspective(1000px);
}
box:nth-child(5):hover {
transform: rotate3d(1, 0, 0, 45deg) translate3d(0, 0, 100px);
}
box:nth-child(6):hover {
transform: translate3d(0, 0, 100px) rotate3d(1, 0, 0, 45deg);
}
box:nth-child(7):hover {
transform: perspective(1000px) rotate3d(1, 0, 0, 45deg) translate3d(0, 0, 100px);
}
box:nth-child(8):hover {
transform: perspective(1000px) translate3d(0, 0, 100px) rotate3d(1, 0, 0, 45deg);
}
box {
padding: 20px;
display: inline-flex;
align-items: center;
justify-content: center;
font-family: monospace;
transition: transform .4s;
background: rgba(255, 0, 0, 0.3);
margin: 20px;
font-size: 12px;
perspective: 1000px;
cursor: pointer;
}
box:nth-child(even) {
background: rgba(0, 0, 255, 0.3);
}
<box>
1. transform: perspective(1000px) translate3d(0,0,100px);
</box>
<box>
2. transform: translate3d(0,0,100px) perspective(1000px);
</box>
<box>
3. transform: rotate3d(1,0,0,45deg) perspective(1000px) translate3d(0, 0, 100px);
</box>
<box>
4. transform: rotate3d(1,0,0,45deg) translate3d(0, 0, 100px) perspective(1000px);
</box>
<box>
5. transform: rotate3d(1,0,0,45deg) translate3d(0, 0, 100px);
</box>
<box>
6. transform: translate3d(0, 0, 100px) rotate3d(1,0,0,45deg);
</box>
<box>
7. perspective(1000px) rotate3d(1,0,0,45deg) translate3d(0, 0, 100px);
</box>
<box>
8. perspective(1000px) translate3d(0, 0, 100px) rotate3d(1,0,0,45deg);
</box>
首先,例如 1 和 2。很明显地显示了 perspective()
如何为 translate3d
工作。
但是没有perspective()
,translate3d
是不是就没用了?
没有。正如我在第一个命令中提到的。
without telling the browser the z-position of element, how can you do 3-dimensional translation?
但是,二维的怎么样?
看看示例 3 和示例 5。它们的行为完全不同。
为什么?因为你做了旋转之后,它的z维度就不再是你的windows'z维度了。方块向上移动 100 * cos(45) = 50px.
因此,5 和 6 的工作方式完全不同,rotate3d(1,0,0,45deg)
和 translate3d(0, 0, 100px)
之间的顺序确实有所不同。
对于 7 和 8,当 z-index 也可用于元素时,会更加明显。它确实不同。
我发现 transform
属性 取决于 perspective()
位置
为什么会这样? transform
的任何其他 rules/limitations?
虽然我觉得很奇怪,但这似乎不是一个错误,因为我能够在 Chrome/FF
中重现它box:nth-child(1):hover {
transform: perspective(1000px) translate3d(0, 0, -100px);
}
box:nth-child(2):hover {
transform: translate3d(0, 0, 100px) perspective(1000px);
}
box {
padding: 20px;
display: inline-flex;
align-items: center;
justify-content: center;
font-family: monospace;
transition: transform .4s;
background: rgba(255, 0, 0, 0.3);
margin: 20px;
font-size: 12px;
perspective: 1000px;
cursor: pointer;
}
box:nth-child(2) {
background: rgba(0, 0, 255, 0.3);
}
<box>
transform: perspective(1000px) translate3d(0,0,100px);
</box>
<box>
transform: translate3d(0,0,100px) perspective(1000px);
</box>
在这两种情况下,您都应该将 perspective
放在首位。如果加在最后会先翻译,不考虑视角
如果我们参考 specification 我们可以看到转换矩阵是如何计算的:
The transformation matrix is computed from the transform and transform-origin properties as follows:
Start with the identity matrix.
Translate by the computed X and Y of transform-origin
Multiply by each of the transform functions in transform property from left to right
Translate by the negated computed X and Y values of transform-origin
正如您在步骤 (3) 中看到的那样,它是从 左到右 (这是另一个问题,您可以在其中获得更多信息并了解顺序的重要性:
在要变换的元素中使用perspective属性也没用。
box:nth-child(1):hover {
transform: perspective(1000px) translate3d(0, 0, -100px);
}
box:nth-child(2):hover {
transform: perspective(1000px) translate3d(0, 0, 100px);
}
box {
padding: 20px;
display: inline-flex;
align-items: center;
justify-content: center;
font-family: monospace;
transition: transform .4s;
background: rgba(255, 0, 0, 0.3);
margin: 20px;
/*perspective: 1000px;*/
font-size: 12px;
cursor: pointer;
}
box:nth-child(2) {
background: rgba(0, 0, 255, 0.3);
}
<box>
transform: perspective(1000px) translate3d(0,0,100px);
</box>
<box>
transform: perspective(1000px) translate3d(0,0,100px);
</box>
为避免与顺序混淆,您可以在父元素中声明透视图,但您需要注意原点,因为它不会相同:
box:nth-child(1):hover {
transform:translate3d(0, 0, -100px);
}
box:nth-child(2):hover {
transform:translate3d(0, 0, 100px);
}
body {
perspective:1000px;
}
box {
padding: 20px;
display: inline-flex;
align-items: center;
justify-content: center;
font-family: monospace;
transition: transform .4s;
background: rgba(255, 0, 0, 0.3);
margin: 20px;
font-size: 12px;
cursor: pointer;
}
box:nth-child(2) {
background: rgba(0, 0, 255, 0.3);
}
<box>
transform: perspective(1000px) translate3d(0,0,100px);
</box>
<box>
transform: perspective(1000px) translate3d(0,0,100px);
</box>
虽然另一个答案已经非常清楚地说明了 perspective()
是如何工作的。但我想让我更具体一点。
box:nth-child(1):hover {
transform: perspective(1000px) translate3d(0, 0, 100px);
}
box:nth-child(2):hover {
transform: translate3d(0, 0, 100px) perspective(1000px);
}
box:nth-child(3):hover {
transform: rotate3d(1, 0, 0, 45deg) perspective(1000px) translate3d(0, 0, 100px);
}
box:nth-child(4):hover {
transform: rotate3d(1, 0, 0, 45deg) translate3d(0, 0, 100px) perspective(1000px);
}
box:nth-child(5):hover {
transform: rotate3d(1, 0, 0, 45deg) translate3d(0, 0, 100px);
}
box:nth-child(6):hover {
transform: translate3d(0, 0, 100px) rotate3d(1, 0, 0, 45deg);
}
box:nth-child(7):hover {
transform: perspective(1000px) rotate3d(1, 0, 0, 45deg) translate3d(0, 0, 100px);
}
box:nth-child(8):hover {
transform: perspective(1000px) translate3d(0, 0, 100px) rotate3d(1, 0, 0, 45deg);
}
box {
padding: 20px;
display: inline-flex;
align-items: center;
justify-content: center;
font-family: monospace;
transition: transform .4s;
background: rgba(255, 0, 0, 0.3);
margin: 20px;
font-size: 12px;
perspective: 1000px;
cursor: pointer;
}
box:nth-child(even) {
background: rgba(0, 0, 255, 0.3);
}
<box>
1. transform: perspective(1000px) translate3d(0,0,100px);
</box>
<box>
2. transform: translate3d(0,0,100px) perspective(1000px);
</box>
<box>
3. transform: rotate3d(1,0,0,45deg) perspective(1000px) translate3d(0, 0, 100px);
</box>
<box>
4. transform: rotate3d(1,0,0,45deg) translate3d(0, 0, 100px) perspective(1000px);
</box>
<box>
5. transform: rotate3d(1,0,0,45deg) translate3d(0, 0, 100px);
</box>
<box>
6. transform: translate3d(0, 0, 100px) rotate3d(1,0,0,45deg);
</box>
<box>
7. perspective(1000px) rotate3d(1,0,0,45deg) translate3d(0, 0, 100px);
</box>
<box>
8. perspective(1000px) translate3d(0, 0, 100px) rotate3d(1,0,0,45deg);
</box>
首先,例如 1 和 2。很明显地显示了 perspective()
如何为 translate3d
工作。
但是没有perspective()
,translate3d
是不是就没用了?
没有。正如我在第一个命令中提到的。
without telling the browser the z-position of element, how can you do 3-dimensional translation?
但是,二维的怎么样?
看看示例 3 和示例 5。它们的行为完全不同。
为什么?因为你做了旋转之后,它的z维度就不再是你的windows'z维度了。方块向上移动 100 * cos(45) = 50px.
因此,5 和 6 的工作方式完全不同,rotate3d(1,0,0,45deg)
和 translate3d(0, 0, 100px)
之间的顺序确实有所不同。
对于 7 和 8,当 z-index 也可用于元素时,会更加明显。它确实不同。