Usually, when I see terms like “painting order” or “stacking context” my brain will start to shut off and my eyes will gloss over. Not that my brain doesn’t normally shut off more often than not, but that’s another topic for another time.
Martin Robinson over at Igalia touches on these concepts using an example that’s pretty easy to grok, even for me. He starts with two boxes that overlap with negative margins.
<div class="blue box">1</div>
<div class="green box">2</div>

Then he introduces a third box that’s a child of the green box. The green box is given a z-index
of -1. As you might expect, both the green and yellow boxes stack below the blue box.
<div class="blue box">0</div>
<div class="green box" style="position: relative; z-index: -1;">-1
<div class="yellow box">-1</div>
</div>

Here’s where my brain started melting. If the z-index
of the green box stays the same at -1 but we give it’s child a massive value, say 1,000, things look… exactly the same.
<div class="blue box">0</div>
<div class="green box" style="position: relative; z-index: -1;">-1
<div class="yellow box" style="position: relative; z-index: 1000;">1000</div>
</div>

I’m sure many of you can already guess (or simply flat out know) why the blue box stays on top, even though changing the yellow box’s z-index
implies it should be on top instead, but I sure didn’t. Martin found the technical answer in the CSS2 specification buried deep down in Appendix E, which he graciously linked up — otherwise, I’m sure I’d never have found it.
We learn from the Appendix E that a stacking context is an atomically painted collection of page items. What does this mean? To put it simply, it means that things inside a stacking context are painted together, as a unit, and that items outside the stacking content will never be painted between them. Having an active
z-index
is one of the situations in CSS which triggers the creation of a stacking context. Is there a way we can adjust our example above so that the third element belongs to the same stacking context as the first two elements? The answer is that we must remove it from the stacking context created by the second element.
So, yeah. As long as the yellow box is a child of the green box, the two form a stacking context that the blue box has no part of. Getting yellow above blue requires removing it from green’s stacking context.

That’s the crux of Martin’s post, but he takes it even further and it’s worth heading over there. If you do, you’ll see how stacking order leads to some bonafide CSS tricks.

It’s not the first time we’ve linked up proof that z-index
is not a level playing field so I’m going to try to commit this to memory the next (and inevitable) time I wrestle with stacking elements.
I am new to coding and trying to learn all i can this helped with what im currently trying to do thank you.
Very good post. I had to check the original to actually understand what the big deal was, because without the code at the beginning, things were a bit difficult to grasp.
Afterwards, it was a bit obvious that if you have 2 elements inside the same div(or any CTN) with inside elements with a certain z-index defined, the z-index of each element inside that wrapper would basically apply only inside the wrapper (div mentioned above).
But yeah, these scenarios are better explained with some code, otherwise they end up being a bit hard to grasp.
Thanks for the insightful post!
Helpful
But if the child has position:absolute; it woukd be above i think?!
Yes, that’s why we need a true absolute index, as the current is relative and it doesn’t cover all life cases. Often u just need an absolute zindex.
A – 1
B – 0
B.C – 1000
So the B.C would stay on top of all. Atm you’d have to manipulate the Dom, but u can’t always do that, ecpecially with modern data-droven frameworks.
I’d suggest “absolute-z-index” property
Are then
z-index
relative to the stacking context?That would be my TLDR; if I understood correctly.