0

This has been asked before but none of the answers seem to be working for me.

My issue is related to a lost z-index when a transformation is applied.

I have an overlay div with a defined z-index, it has a sibling with no z-index and this div contains a child with a z-index greater than the overlay. This child can be dragged around.

At some point I rotate this sibling and it's child loses the z-index.

How can I prevent this from happening?

I tried several solutions attemps like transform-style: flat; or transform-style: preserve-3d; but with no luck

This is the code

HTML

<div class="main">
  <div class="some_container">
    <div class="drag"></div>
  </div>
</div>

<div class="overlay"></div>

<br><br><br>

<button>rotate!</button>

CSS

body {
    padding: 20px
}

div {
    border: 1px solid black;
    width: 50px;
    height: 50px;
}

.main {
    border: 1px dashed blue;
    padding: 15px;
}

.some_container {
    position: relative;
    background-color: green;
}

.overlay {
    background-color: red;
    position: absolute;
    left: 35px;
    top: 35px;
    z-index: 5
}

.drag {
    position: relative;
    width: 30px;
    height: 30px;
    background-color: lime;
    z-index: 10;
    cursor: move;
}

.rotated {
    transform: rotateZ(15deg);
}

.rotated .drag {
    background-color: yellow;
    transform: rotateZ(-15deg);
    position: relative;
    z-index: 100;
  transform-style: flat;
}

JS

$(".drag").draggable();

$("button").click(function()
{
    $(".some_container").addClass("rotated");
});

fiddle: https://jsfiddle.net/2zkn9dap/

Matías Cánepa
  • 5,770
  • 4
  • 57
  • 97

2 Answers2

1

The transform that you have in your .rotated class creates a new stacking context that is changing the order that the elements are layered. A great explanation with more detail can be found here: z-index is canceled by setting transform(rotate)

The best approach to solving this is to move the .drag div to be a sibling of the .overlay and .some_container div. Then update your JS to add the rotated class to the green and yellow squares so they are both rotated. Otherwise, you'll never be able to get the yellow square on top of the red one consistently, because the z-index of the parent, in this case the .some_container div takes precedence.

dukedevil294
  • 1,285
  • 17
  • 31
0

  $("button").click(function(){
      $(".green").addClass("rotated")
      $(".lime").addClass("rotated").css({backgroundColor: 'yellow'});
  });
body {
  padding: 20px
} 
div {
  border: 1px solid black;
  width: 50px;
  height: 50px;
}
.container {
  border: 1px dashed blue;
  padding: 15px;
}
.green {
  position: absolute;
  background-color: green;
  z-index: 2;
} 
.red {
  background-color: red;
  position: absolute;
  left: 35px;
  top: 35px;
  z-index: 3;
}
.lime {
  position: absolute;
  width: 30px;
  height: 30px;
  background-color: lime;
  z-index: 4;
  cursor: move;
}
.rotated {
  transform: rotateZ(15deg);
}
<div class="container">
  <div class="green">
  </div>
  <div class="lime"></div>
</div>

<div class="red"></div>

<br><br><br>

<button>rotate!</button>
<script src="http://code.jquery.com/jquery-3.3.1.js"></script>

Change the position: relative to absolute of .lime. If you don't want to rotate the '.lime' div, then remove `.addClass("rotated") on the 4th line of the script.