Search code examples
cssz-index

Why don't root elements of stacking contexts stack if their properties differ?


I was very surprised today when an element with a transform that isn't none didn't stack above an element with a position that is absolute despite having a higher z-index. However, adding position:absolute|relative to the former element made z-index perform as expected between them.

Take a look: I expected in the following for the green square (with transform:translateX(0)) to stack above them all the others from having the highest z-index, but it only stacks above the blue square which precedes it in the DOM. I attribute it to the blue square having z-index:0 and some degenerate behavior, as though both have z-index:0.

div {
  opacity:0.8;
  width:100px;
  height:100px;
}
body {
  margin:10px;
}
<div style="background-color:blue; position:absolute; top:0px; left:0px; z-index:0;">
</div>
<div style="background-color:green; transform:translateX(0); z-index:2;">
</div>
<div style="background-color:red; position:absolute; top:20px; left:20px; z-index:1;">
</div>

My expectation was that all of the elements above are in the root stacking context. What's going on?


Solution

  • z-index works on flex items and positioned elements(an element is “positioned” means that it has a position value other than static, e.g., relative, absolute and fixed). If you try to set a z-index on an element with no position specified, it will do nothing.

    So, just set position of green div to relative/absolute/fixed, it will be stack on top of all the div.

    div {
      opacity:0.8;
      width:100px;
      height:100px;
    }
    body {
      margin:10px;
    }
    <div style="background-color:blue; position:absolute; top:0px; left:0px; z-index:0;">
    </div>
    <div style="background-color:green;position:relative; transform:translateX(0); z-index:2;">
    </div>
    <div style="background-color:red; position:absolute; top:20px; left:20px; z-index:1;">
    </div>