如果 parent 元素有自己的转换,为什么 CSS translateZ 会被忽略?

Why CSS translateZ is ignored if parent element has a transform of its own?

谁能解释这种行为?

我有三个嵌套元素:一个容器 div、一个子容器 div 和一个“shape/image”div。标记如下:

<html>
  <div class="container">
    <div class="subcontainer">
      <div class="shape"></div>
    </div>
  </div>
</html>

当我对形状应用 transform: translateZ() 时,显然它只有在其中一个 parent 应用了一些 perspective 时才有效。它不一定是直接的 parent,它可以是 parent 的 parent div(容器)。当容器有 perspective 时,形状在 z 方向上移动很好。但是,当子容器 (parent) 在 transform 中有东西时,除了 unset 之外,形状中的 translateZ() 将被完全忽略。当然,将 perspective 应用于直接 parent 会使形状中的 translateZ() 起作用,但我想了解 parent transform 中的什么阻止了 perspective 看形状:

以下作品:

.container{
  perspective: 1000px;
}

.subcontainer{
  transform: unset;     // <- or if this is not present at all
}

.shape{
  transform: translateZ(300px);
}

以下无效:

.container{
  perspective: 1000px;
}

.subcontainer{
  transform: scale(1.001);
}

.shape{
  transform: translateZ(300px);    // <- this is fully ignored
}

这是代码笔中的this example

编辑: 在许多文档中,我读到 perspective 必须是 parent 元素中的 属性 集。但是 MDN 似乎表明它实际上可以在 transform 规则内的预期元素本身中设置。那么,parent中的perspective: 500px是否等同于child中的transform: perspective(500px)

来自the specification:

By default, transformed elements do not create a 3D rendering context and create a flattened representation of their content. However, since it is useful to construct hierarchies of transformed objects that share a common 3-dimensional space, this flattening behavior may be overridden by specifying a value of preserve-3d for the transform-style property. This allows descendants of the transformed element to share the same 3D rendering context.

所以只需将 transform-style:preserve-3d 添加到子容器元素,grand-parent 的视角将得到尊重:

.container{
  background: #f4f7be;
  height: 100vh;
  width: 100vw;
  display: flex;
  justify-content: center;
  align-items: center;
  perspective: 1000px;
}

.subcontainer{
  background: #baf7f6;
  width: 70%;
  height: 70%;
  display: flex;
  justify-content: center;
  align-items: center;
  transform: scale(1.001);
  transform-style:preserve-3d;
}

.shape{
  background: #555;
  width: 40%;
  height: 50%;
  clip-path: polygon(50% 0%, 0% 100%, 100% 100%);
  transform: translateZ(300px);
}
<html>
  <div class="container">
    <div class="subcontainer">
      <div class="shape"></div>
    </div>
  </div>
</html>


So, is perspective: 500px in the parent equivalent to transform: perspective(500px) in the child?

不完全相同,因为您需要考虑其他因素,例如 parent 维度、transform-origin、perspective-origin 等

一个简单的例子:

.box {
  padding: 20px;
  border: 1px solid;
}

.box>div {
  width: 100px;
  height: 100px;
  background: red;
}
<div class="box" style="perspective:100px;">
  <div style="transform:translateZ(10px);"></div>
</div>

<div class="box">
  <div style="transform:perspective(100px) translateZ(10px);"></div>
</div>

因产地不同。在第一种情况下,透视将使用 parent 的中心作为原点(因为默认情况下 perspective-origin 是中心)。在第二种情况下,元素的中心将被用作原点(因为transform-origin默认是中心)

有关更多详细信息和示例的相关问题: