Have you ever added z-index: 999999; to a dropdown or modal dialog, only for it to remain stubbornly hidden behind a sidebar? The root cause is not an insufficiently large number; it is a fundamental misunderstanding of Stacking Contexts.
Even without any z-index declared, the browser engine renders elements in a strict back-to-front 3D stacking order along the Z-axis:
1. Root Background & Borders: The baseline canvas of the document.
2. Negative z-index: Positioned elements with z-index < 0.
3. Non-positioned Blocks: Standard <div>, <p>, <h1> in normal flow.
4. Floated Elements: Non-positioned floating boxes.
5. Inline Elements: Text nodes, links, and inline tags.
6. Positioned (z-index: auto / 0): Elements with position relative/absolute/fixed.
7. Positive z-index: Elements with z-index > 0 (highest numbers render closest to the eye).
A Stacking Context is an isolated layer tree. Elements inside a stacking context cannot escape it to compete with elements in an outside context. A new stacking context is created by:
• Positioned element (relative/absolute) with an explicit z-index other than auto.
• position: fixed or position: sticky.
• opacity less than 1.
• Elements using transform, filter, perspective, or clip-path.
• Modern isolation: isolate; property.
To prevent child components from accidentally leaking z-indexes or getting trapped under sibling components, assign isolation: isolate to create a clean, scoped boundary:
.modal-wrapper {
isolation: isolate; /* Clean, encapsulated stacking context */
z-index: 1000;
}
Boost your CSS and front-end development proficiency by exploring these closely connected topics:
Understand margins, borders, padding, content and the universal box-sizing fix.
Master 1D alignment, justify-content, align-items, flex-wrap and responsive flow.
Build powerful two-dimensional grid layouts with template areas and fr units.
Eliminate styling conflicts and master selector weights from 0,0,0,1 to !important.