The z-index property in CSS is a powerful tool for controlling the stacking order of elements on a webpage. It determines which elements appear in front of or behind others when they overlap. However, it can be frustrating when z-index doesn’t behave as expected. In this blog, we’ll explore how z-index works, common pitfalls, and how to troubleshoot issues, keeping things clear for intermediate developers.
What is Z-Index?
The z-index property specifies the stack order of an element along the z-axis, which is the depth axis perpendicular to the screen. Elements with a higher z-index are displayed in front of those with a lower z-index. If no z-index is set, elements stack based on their order in the HTML document (later elements appear above earlier ones).
For z-index to work, the element must have a position property set to relative, absolute, fixed, or sticky. Without this, z-index has no effect.
Here’s a basic example:
.div1 {
position: relative;
z-index: 10;
background: blue;
width: 100px;
height: 100px;
}
.div2 {
position: relative;
z-index: 5;
background: red;
width: 100px;
height: 100px;
margin-top: -50px; /* Overlaps div1 */
}In this example, div1 will appear above div2 because it has a higher z-index (10 > 5).
Why Isn’t Z-Index Working?
When z-index doesn’t work as expected, it’s often due to one of these common issues:
1. Missing or Incorrect position Property
As mentioned, z-index only works on positioned elements. If an element has position: static (the default), z-index is ignored.
Fix: Ensure the element has position: relative, absolute, fixed, or sticky.
/* This won’t work */
.div1 {
z-index: 100;
background: blue;
}
/* This works */
.div1 {
position: relative;
z-index: 100;
background: blue;
}2. Stacking Context Issues
A stacking context is a group of elements that share a common parent that defines their stacking order. A new stacking context is created by properties like:
position: absolute or relative with a z-index other than auto
opacity less than 1
transform or filter properties
isolation: isolate
If an element is inside a stacking context, its z-index is relative to that context, not the global document. This can cause unexpected stacking behavior.
Example:
<div class="parent" style="position: relative; z-index: 1;">
<div class="child" style="position: absolute; z-index: 1000;">Child</div>
</div>
<div class="sibling" style="position: relative; z-index: 2;">Sibling</div>Here, the child with z-index: 1000 is still behind sibling because parent creates a stacking context with z-index: 1. The child’s z-index only applies within the parent’s stacking context.
Fix: Adjust the z-index of the parent or avoid creating a stacking context unnecessarily.
3. Parent-Child Relationships
An element’s z-index is confined to its parent’s stacking context. If a parent has a lower z-index than another element, its children cannot appear above that element, no matter how high their z-index is.
Fix: Ensure the parent’s z-index is high enough, or move the child outside the parent if possible.
4. Overlapping Elements Without Positioning
If elements overlap but neither has a position property, the HTML source order determines stacking. The element that appears later in the HTML will be on top.
Fix: Add position and z-index to control the stacking explicitly.
Debugging Tips
Check Positioning: Use browser developer tools to verify that the element has a position other than static.
Inspect Stacking Contexts: Look for parent elements with properties like z-index, opacity, or transform that might create a stacking context.
Simplify the Code: Temporarily remove unrelated styles to isolate the issue.
Use High Z-Index Values for Testing: Try a very high z-index (e.g., 9999) to rule out conflicts with other elements.
Practical Example
Let’s create a simple scenario where two overlapping boxes should stack correctly:
<div class="box blue"></div>
<div class="box red"></div>.box {
width: 100px;
height: 100px;
position: absolute;
}
.blue {
background: blue;
z-index: 10;
top: 50px;
left: 50px;
}
.red {
background: red;
z-index: 5;
top: 70px;
left: 70px;
}In this example, the blue box (z-index: 10) will appear above the red box (z-index: 5) because it has a higher z-index and both boxes are positioned.
Conclusion
Understanding z-index requires knowing how positioning and stacking contexts work. By ensuring elements are properly positioned, checking for stacking context issues, and debugging systematically, you can resolve most z-index problems. Keep practicing with small examples like the one above to build confidence in managing element stacking in your projects.