【问题标题】:Why CSS translateZ is ignored if parent element has a transform of its own?如果父元素有自己的变换,为什么 CSS translateZ 会被忽略?
【发布时间】:2021-03-30 20:56:32
【问题描述】:

谁能解释这种行为?

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

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

当我将transform: translateZ() 应用于形状时,显然只有在其中一位父母应用了一些perspective 时它才会起作用。它不一定是直接父级,它可以是父级的父级div(容器)。当容器有perspective 时,形状在z 方向上移动很好。但是,当子容器(父容器)在 transform 中包含 unset 以外的内容时,形状中的 translateZ() 将被完全忽略。当然,将perspective 应用于直接父级会使形状中的translateZ() 起作用,但我想了解父级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
}

这里是 codepen 中的this example

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

【问题讨论】:

    标签: html css css-transforms perspective


    【解决方案1】:

    来自the specification:

    默认情况下,转换后的元素不会创建 3D 渲染上下文,而是创建其内容的扁平化表示。但是,由于构造共享公共 3 维空间的变换对象的层次结构很有用,因此可以通过为 transform-style 属性指定值 preserve-3d 来覆盖这种展平行为。 这允许转换后元素的后代共享相同的 3D 渲染上下文

    因此,只需将transform-style:preserve-3d 添加到子容器元素中,就会尊重祖父母的视角:

    .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>

    那么,parent 中的 perspective: 500px 是否等同于 child 中的 transform: perspective(500px)?

    不完全等效,因为您需要考虑其他因素,例如父维度、变换原点、透视原点等

    一个简单的例子:

    .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>

    差异是由于产地。在第一种情况下,透视将使用父级的中心作为原点(因为perspective-origin 默认为中心)。第二种情况,将元素的中心作为原点(因为transform-origin默认为中心)

    更多细节和示例的相关问题:

    perspective and translateZ moves diagonally

    Why perspective isn't giving the same result when some styles are updated?

    CSS 3d transform doesn't work if perspective is set in the end of property

    【讨论】:

    • 所以,对于第一个,当父元素没有指定变换时,即使您没有在变换样式中指定任何内容,“保留 3D 特征”也不是很奇怪父母?
    • @Adriano_Pinaffo 这并不奇怪,因为变换样式并不能真正控制 3D 功能。 3D 由透视控制(您可以在此处找到完整的详细信息:drafts.csswg.org/css-transforms-2/#3d-transform-rendering)但在某些情况下,某些层次结构(可能是性能问题)禁用了 3D 上下文,您可以使用变换样式再次激活它.就像您的情况一样,具有变换的元素不会将 3D 渲染上下文传播到其子元素。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多