【问题标题】:How to control z-index when using perspective and transform?使用透视和变换时如何控制z-index?
【发布时间】:2022-02-01 02:46:56
【问题描述】:

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

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

这是一个重现问题的 sn-p:

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

我需要的是 &lt;div class="test"&gt; 显示在所有人面前。喜欢this。但我不想在方形 div 上设置 z-index,因为它们将放置在 flex 布局网格内。

有没有办法让一个元素总是呈现在所有其他元素的前面?不知道他放在哪里或堆栈上下文发生了什么。

【问题讨论】:

    标签: html css css-transforms


    【解决方案1】:

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

    我只是改变了所有子元素的 z-index,使用 js,使那些首先具有更高 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>

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

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        【解决方案3】:

        我所做的只是将带有 .test 类的 div 移动到带有翻转元素的 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>

        【讨论】:

        • 请仔细阅读我的问题。我提供了该项目的图片。当然,如果我将 div 移到外面,那么它将显示在另一个 div 的前面,因为它们共享相同的上下文。问题是“测试” div 代表图像中显示的菜单(并且它必须留在里面)。
        猜你喜欢
        • 2016-11-18
        • 2011-10-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-06-03
        • 2012-12-17
        • 2012-12-24
        相关资源
        最近更新 更多