z-index when using ::after under element
Specifying z-index
you are creating a new stacking content;
if this is done only on the child ::after
pseudo-elem the parent won't establish a new stacking content and everything will work as expected.
But adding z-index
on the parent element will start a new stack (which will also wrap the child-stack..).
And if you look at the first 2 points on stack rendering specification you'll see background will be rendered before other child-stacks:
Within each stacking context, the following layers are painted in back-to-front order:
- the background and borders of the element forming the stacking context.
- the child stacking contexts with negative stack levels (most negative first).
- ... ...
here's an example, to clarify the different rendering behavior for nested stacking background.
position: relative
is not optional; with the default position:static
, z-index
has no effect.
Your div and its ::after pseudo-element are members of the same stacking context, in this case the root stacking context. The new stacking context you give the pseudo-element would be used as a reference to its children (which are non-existent), but the z-index
value applies to the current stacking context. And the CSS spec dictates the following paint order for each stacking context:
Within each stacking context, the following layers are painted in back-to-front order:
- the background and borders of the element forming the stacking context.
- the child stacking contexts with negative stack levels (most negative first).
- the in-flow, non-inline-level, non-positioned descendants.
- the non-positioned floats.
- the in-flow, inline-level, non-positioned descendants, including inline tables and inline blocks.
- the child stacking contexts with stack level 0 and the positioned descendants with stack level 0.
- the child stacking contexts with positive stack levels (least positive first).
Look, child stacking contexts with negative stack levels, such as your div::after
are painted before the positioned descendants with stack level 0, such as the div
itself. This explains the behavior you noticed.