You will be able to control which overlapping CSS elements appear on top by using z-index with positioned elements and stacking contexts.
What it is
z-index is a CSS property that changes the stacking order of elements that overlap. Think of the page as a stack of transparent sheets: elements with a higher z-index are placed closer to the viewer. It affects elements that participate in stacking, especially positioned elements such as position: relative, absolute, fixed, and sticky, as well as flex and grid items. The default value is auto, which usually follows normal painting order.
Related terms: stacking context, positioned element, DOM order, layering.
Why it matters
- Keeps modals, dropdowns, tooltips, and notifications above page content.
- Prevents one component from accidentally covering another.
- Makes overlap behavior predictable when elements are absolutely positioned.
- Helps debug “why is this element hidden?” issues.
Syntax or steps
- Make the element positioned:
position: relative;,absolute;,fixed;, orsticky;. - Set
z-indexto an integer, such as10, orauto. - Compare elements only inside the same stacking context.
- If a parent creates a stacking context, child
z-indexvalues cannot escape that parent.
Smallest useful pattern:
.modal {
position: fixed;
z-index: 1000;
}
Example
<!DOCTYPE html>
<html>
<head>
<style>
.card {
position: relative;
z-index: 1;
background: #fff;
padding: 1rem;
border: 1px solid #ccc;
}
.modal {
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 1000;
background: rgba(0, 0, 0, 0.5);
display: grid;
place-items: center;
}
.modal-box {
background: #fff;
padding: 1rem;
}
</style>
</head>
<body>
<div class="card">Page card</div>
<div class="modal">
<div class="modal-box">Modal content</div>
</div>
</body>
</html>
Part by part:
.cardis positioned and givenz-index: 1, so it participates in stacking..modalisposition: fixed, so it can usez-index.top,right,bottom, andleftmake the modal cover the viewport.z-index: 1000places the modal above the card because both are in the root stacking context.
Common mistakes
- Using z-index on a static element. Fix: add
position: relative;or another positioning value. - Assuming a larger number always wins. Fix: check stacking contexts; a child with
z-index: 9999can still be behind a sibling if its parent has a lower stacking context. - Using huge random values like 999999. Fix: use a small scale, such as 10, 100, 1000, and document what each range means.
- Forgetting that negative z-index can go behind the parent background. Fix: test with
z-index: 0or adjust the parent stacking context.
When to use it
Use z-index when elements overlap and you need to control visual layering. Use DOM order or order when you only need to change layout sequence without overlap.
| Need | Use | Why |
|---|---|---|
| Modal above page | z-index |
Controls overlap layering. |
| Reorder flex items | order |
Changes layout order, not stacking. |
| Simple non-overlapping content | DOM order | Later elements naturally paint above earlier ones. |
Practice
Guided exercise: create two overlapping boxes. Make the first box position: relative; z-index: 2; and the second position: relative; z-index: 1;. Expected output: the first box appears on top.
Challenge: add a parent with position: relative; z-index: 1; and a child with position: relative; z-index: 999;. Place a sibling outside the parent with position: relative; z-index: 2;. Hint: the sibling may still appear above the child because the parent creates a stacking context.
Quick check
Question: Why might z-index: 9999 fail to bring an element to the front?
Answer: Because the element may be inside a stacking context whose parent has a lower stacking order, or the element may not be positioned.
Summary
z-index controls visual layering for positioned elements and flex or grid items within the same stacking context. Higher numbers do not automatically win across the whole page; stacking contexts decide the boundaries.