If you’re a beginner trying to build a popup, dropdown, modal, or tooltip and it's hiding behind something you've likely yelled at your screen:
But I gave it z-index: 9999 then WHY isn’t it on top?
Same here. I thought z-index was just about giving a higher number to an element to make it appear in front. But in practice? It felt like black magic. Things didn’t layer right, overlays disappeared, and sometimes… absolutely nothing worked.
Turns out, it’s not the number. It’s the context.
You’ve done it too:
What is z-index?
In the simplest way: z-index controls what comes on top and what stays behind.
But there's a catch, z-index only works if your element is in the right stacking context.
Let’s decode that word...
What is Stacking Context?
Imagine you’re placing stickers on transparent sheets. Some sheets are above others, and each sheet has stickers with their own order.
In CSS, those transparent sheets are stacking contexts. If your element is inside a lower sheet, it’ll never appear on top, no matter the z-index.
Common ways stacking contexts are created:
- Any element with position: relative, absolute, fixed, or sticky & z-index
- Using transform, filter, perspective, opacity < 1, etc. Even if you give something z-index: 99999, if it’s inside a stacking context that’s lower than another, it won't rise above.
Real-Life Dev Mistake (aka What I Did)
I had this:
<div class="parent">
<div class="modal">I’m a modal</div>
</div>
And in CSS:
.parent {
position: relative;
z-index: 1;
}
.modal {
position: absolute;
z-index: 9999;
}
Still... the modal was hidden behind a navbar.
The reason? The navbar was in another stacking context, one that had a higher position + z-index combo.
Fix: Bring the Right Parent Up
The solution isn’t just to give your element a higher z-index. You often need to check its parent container too. That’s the real culprit in 90% of cases.
How to fix:
- Find the stacking context your element lives in
- Make sure that context itself can go on top
- Adjust the parent’s z-index accordingly
Example:
.modal-wrapper {
position: fixed;
top: 0;
left: 0;
z-index: 9999;
}
Or just take it out of other containers that limit its stacking.
Common Situations Where z-index
Breaks
Use Case | What Goes Wrong | Fix It Like This |
---|---|---|
Tooltip hidden | Tooltip is inside a lower stacking context | Move it outside / raise parent’s z-index
|
Modal below overlay | Modal lives inside a positioned container | Use position: fixed and give high z-index
|
Dropdown under navbar | Navbar has higher z-index + stacking context |
Adjust navbar or dropdown stacking context |
Quick Debug Checklist
- Is your element positioned (relative, absolute, fixed)?
- Is there a parent creating a stacking context?
- Are other elements using high z-index + position?
- Are you using transform, opacity, filter on parents?
If yes => these might be making your life harder.
Use browser dev tools => right-click => Inspect => check z-index and stacking context in Styles tab.
One more, When you don’t give a z-index, it defaults to auto.
And here’s the deal: auto means "I’ll stay in line with my stacking context." So your element might not get layered properly — even if you think it should.
Be explicit. Don’t just trust the browser.
FAQ's
Q: I gave z-index: 99999 but it’s still not showing?
A: Check the parent stacking context. Your element can’t break free of it unless you move it or raise the parent too.
Q: My tooltip is inside a card and stays behind. Why?
A: That card probably has overflow: hidden or is positioned. Try moving the tooltip outside the card or adjusting its z-index and positioning.
Q: Do SVGs or images affect stacking context?
A: Only if you add transform, opacity, or other properties that create stacking context.
Conclusion
z-index is not broken, it’s just misunderstood.
Once you get how stacking context works, z-index will feel way more predictable. It’s not about the biggest number, it’s about being in the right layer first.
So the next time something "refuses" to come on top, you’ll know:
Don’t blame the z-index. Blame the parent.
Top comments (0)