Explain this behavior:
<div style="z-index: 1"></div>
<div></div>
<div></div>
<div></div>
div {
position: relative;
background: red;
width: 100px;
height: 100px;
}
div:before {
position: absolute;
background: blue;
width: 100px;
height: 100px;
z-index: -1;
content: "";
left: -5px;
top: -5px;
}
Only difference is the first div has z-index: 1 set.
Setting a positioned element's
z-index
to anything other thanauto
(the initial value) causes the element to generate a new stacking context for its descendant boxes.This prevents any of its descendants from appearing below it, including the
div:before
pseudo-element, even if theirz-index
is negative. Of course, any descendant with a negativez-index
will continue to appear below a descendant with a zero or positivez-index
within the containing element, but that containing element will always be at the very back.1The rest of your
div
elements that don't have az-index
set will use the initial value instead, and therefore not generate stacking contexts for their pseudo-elements, allowing the pseudo-elements to appear below the real elements. The stacking context in which they are drawn instead is that ofbody
.1 Note that the content of a stacking context root will still appear above the background of a descendant with a negative
z-index
. This is intentional, and is covered in greater detail in this answer, with relevant links to the spec.