使用透视和变换时如何控制z-index?

How to control z-index when using perspective and transform?

我读过很多关于 z-index 以及变换和透视如何破坏他的上下文的页面。我明白为什么我的代码不工作我不知道如何让它工作(或至少使用和替代)。

如图所示,select 菜单被下面的卡片覆盖。

这里是问题重现的片段:

.square { position: relative; width: 100%; padding-bottom: 100%; }
.square>* { position: absolute; width: 100%; height: 100%; }

/* flip */
/* u -> uncontroled / c -> controled */
.flip { perspective: 200em; }
.flip .front, .flip .back {
 -webkit-backface-visibility: hidden; -moz-backface-visibility: hidden;
 backface-visibility: hidden; position: absolute;
 top: 0; left: 0; right: 0; bottom: 0;
}
@supports (-webkit-transform-style: preserve-3d) or (-moz-transform-style: preserve-3d) or (transform-style: preserve-3d) {
 .flip .front, .flip .back { 
  -webkit-transform-style: preserve-3d; -moz-transform-style: preserve-3d; transform-style: preserve-3d; transition: 1s;
 }
}
/* -> horizontal */
.flip .front { z-index: 2; transform: rotateY(0deg); perspective: none;}
.flip .back { transform: rotateY(-180deg); }
.flip.u:hover .back, .flip.c.active .back { transform: rotateY(0deg); }
.flip.u:hover .front, .flip.c.active .front { transform: rotateY(180deg); }
/* -> vertical */
.flip.vertical .back { transform: rotateX(-180deg); }
.flip.vertical.u:hover .back, .flip.vertical.c.active .back { transform: rotateX(0deg); }
.flip.vertical.u:hover .front, .flip.vertical.c.active .front { transform: rotateX(180deg);  }

.test {
 position: absolute; top: 70%; left: 10%; background-color: green;
 height: 100px; width: 10px; z-index: 100;
}
<div style="width: 100px; background-color: black">
  <div class="square flip u">
    <div class="front" style="background-color: blue">
      Front
      <div class="test"></div>
    </div>
    <div class="back" style="background-color: red">Back</div>
  </div>
  <hr >
  <div class="square flip u">
    <div class="front" style="background-color: blue">Front</div>
    <div class="back" style="background-color: red">Back</div>
  </div>
</div>

我需要的是显示在所有人面前的<div class="test">。喜欢this。但我不想在方形 div 上设置 z-index,因为它们将被放置在 flex layout Grid 中。

有没有办法让某个元素始终呈现在所有其他元素之前?不知道他放在哪里或堆栈上下文发生了什么。

我所做的只是将带有 class .testdiv 移动到带有翻转元素的 div 之外。

.square {
  position: relative;
  width: 100%;
  padding-bottom: 100%;
}

.square>* {
  position: absolute;
  width: 100%;
  height: 100%;
}


/* flip */


/* u -> uncontroled / c -> controled */

.flip {
  perspective: 200em;
}

.flip .front,
.flip .back {
  -webkit-backface-visibility: hidden;
  -moz-backface-visibility: hidden;
  backface-visibility: hidden;
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
}

@supports (-webkit-transform-style: preserve-3d) or (-moz-transform-style: preserve-3d) or (transform-style: preserve-3d) {
  .flip .front,
  .flip .back {
    -webkit-transform-style: preserve-3d;
    -moz-transform-style: preserve-3d;
    transform-style: preserve-3d;
    transition: 1s;
  }
}


/* -> horizontal */

.flip .front {
  z-index: 2;
  transform: rotateY(0deg);
  perspective: none;
}

.flip .back {
  transform: rotateY(-180deg);
}

.flip.u:hover .back,
.flip.c.active .back {
  transform: rotateY(0deg);
}

.flip.u:hover .front,
.flip.c.active .front {
  transform: rotateY(180deg);
}


/* -> vertical */

.flip.vertical .back {
  transform: rotateX(-180deg);
}

.flip.vertical.u:hover .back,
.flip.vertical.c.active .back {
  transform: rotateX(0deg);
}

.flip.vertical.u:hover .front,
.flip.vertical.c.active .front {
  transform: rotateX(180deg);
}

.test {
  position: absolute;
  top: 30%;
  left: 3%;
  background-color: green;
  height: 100px;
  width: 10px;
  z-index: 10;
}
<div style="width: 100px; background-color: black">
  <div class="square flip u">
    <div class="front" style="background-color: blue">
      Front

    </div>
    <div class="back" style="background-color: red">Back</div>
  </div>
  <div class="test"></div>
  <hr>
  <div class="square flip u">
    <div class="front" style="background-color: blue">Front</div>
    <div class="back" style="background-color: red">Back</div>
  </div>
</div>

在过去的几年里没有人找到解决方案,所以这里是我最终所做的(作为解决我的特定问题的替代方案):

我刚刚使用 js 更改了所有子元素的 z-index,使首先具有更高 z-index 的那些子元素。

var targets = document.getElementsByClassName("invertChildZOrder");

var i;
for (i = 0; i < targets.length; i++) {
  target = targets[i];
  for (var i = 0; i < target.childNodes.length; i++) {
    var childNode = target.childNodes[i];
    if (childNode.className == "square flip u") {
      childNode.style.zIndex = "" + (target.childNodes.length - i);
    }        
  }
}
.square { position: relative; width: 100%; padding-bottom: 100%; }
.square>* { position: absolute; width: 100%; height: 100%; }

/* flip */
/* u -> uncontroled / c -> controled */
.flip { perspective: 200em; }
.flip .front, .flip .back {
  -webkit-backface-visibility: hidden; -moz-backface-visibility: hidden;
  backface-visibility: hidden; position: absolute;
  top: 0; left: 0; right: 0; bottom: 0;
}
@supports (-webkit-transform-style: preserve-3d) or (-moz-transform-style: preserve-3d) or (transform-style: preserve-3d) {
  .flip .front, .flip .back { 
    -webkit-transform-style: preserve-3d; -moz-transform-style: preserve-3d; transform-style: preserve-3d; transition: 1s;
  }
}
/* -> horizontal */
.flip .front { z-index: 2; transform: rotateY(0deg); perspective: none;}
.flip .back { transform: rotateY(-180deg); }
.flip.u:hover .back, .flip.c.active .back { transform: rotateY(0deg); }
.flip.u:hover .front, .flip.c.active .front { transform: rotateY(180deg); }
/* -> vertical */
.flip.vertical .back { transform: rotateX(-180deg); }
.flip.vertical.u:hover .back, .flip.vertical.c.active .back { transform: rotateX(0deg); }
.flip.vertical.u:hover .front, .flip.vertical.c.active .front { transform: rotateX(180deg);  }

.test {
  position: absolute; top: 70%; left: 10%; background-color: green;
  height: 100px; width: 10px; z-index: 100;
}
 <div class="invertChildZOrder" style="width: 100px; background-color: black">
  <div class="square flip u">
    <div class="front" style="background-color: blue">
      Front
      <div class="test"></div>
    </div>
    <div class="back" style="background-color: red">Back</div>
  </div>
  <hr >
  <div class="square flip u">
    <div class="front" style="background-color: blue">Front</div>
    <div class="back" style="background-color: red">Back</div>
  </div>
</div>

如你所想。这只能部分解决问题。如果按钮上的方块有另一个菜单,但这次是向上而不是向下,我们也会遇到同样的问题。

我采取了不同的方法。动画完成后,我删除了动画 class。我认为这是一个更简单的解决方案(我也浪费了数小时试图弄清楚发生了什么......)