首页 > 解决方案 > 如何防止孩子继承 3d 转换 CSS3?

问题描述

如何防止孩子继承 3d 转换 CSS3?

我有一个父 div 和一个子 div,现在我想让父使用 3d 转换,而子 div 保持在前面。

例子:

.parent {
  transform: rotateX(33deg) rotateY(66deg) rotateZ(99deg);

  position: relative;
  width: 300px;
  height: 300px;
  margin: 50px auto;
  border: 4px solid darkblue;
}

.child {
  position: absolute;
  width: 80px;
  height: 80px;
  background: aqua;
}
<div class="parent">
  <div class="child">
    I'am a child want keep front.
  </div>
</div>

设置反向旋转,或设置无变换是无效的。

.parent {
  transform: rotateX(33deg) rotateY(66deg) rotateZ(99deg);

  position: relative;
  width: 300px;
  height: 300px;
  margin: 50px auto;
  border: 4px solid darkblue;
}

.child {
  transform: rotateX(-33deg) rotateY(-66deg) rotateZ(-99deg);

  position: absolute;
  width: 80px;
  height: 80px;
  background: aqua;
}
<div class="parent">
  <div class="child">
    I'am a child want keep front.
  </div>
</div>

标签: csscss-transforms

解决方案


首先,您应该通过在父项中设置来使父项的子项定位在 3D 空间中,然后您可以以父项的相反transform-style: preserve-3d;顺序将变换函数应用于想要保持在前面的子元素。

.parent {
  transform: rotateX(33deg) rotateY(66deg) rotateZ(99deg);
  /* Notice! You should make the children of the parent positioned in the 3D-space. */
  transform-style: preserve-3d;

  position: relative;
  width: 300px;
  height: 300px;
  margin: 50px auto;
  border: 4px solid darkblue;
}

.child {
  /* Notice! You should apply the opposite order of rotations (transform functions) from the parent element. */
  transform: rotateZ(-99deg) rotateY(-66deg) rotateX(-33deg);
  position: absolute;
  width: 80px;
  height: 80px;
  background: aqua;
}
<div class="parent">
  <div class="child">
    I'am a child want keep front.
  </div>
</div>

TL;博士

为什么我们应该使用逆序

根据transform-function - CSS: Cascading Style Sheets | MDN

使用矩阵乘法的变换函数按从右到左的顺序组合,矩阵乘法不满足交换律,所以我们应该使用逆序来抵消父变换。

例子:

rotateX(33deg) = matrixA, rotateY(66deg) = matrixB, rotateZ(99deg) = matrixC

我们可以得到rotateX(-33deg) = matrixA^-1, rotateY(-66deg) = matrixB^-1, rotateZ(-99deg) = matrixC^-1(参见:可逆矩阵 - 维基百科旋转矩阵 - 维基百科

我们可以计算孩子的点,与父母一起旋转rotatedPoint = originPoint * matrixA * matrixB * matrixC

我们想让这些点在它的原点位置,所以我们应该这样做,resultPoint = rotatedPoint * matrixC^-1 * matrixB^-1 * matrixA^-1因为矩阵乘法不满足交换律


推荐阅读