Z-Index Control
- Manage stacking order and layered components using z-index effectively.
What is Z-Index ?
Z-index controls the vertical stacking order of elements when they overlap.
Think in layers:
Higher z-index → closer to the user
Lower z-index → further away
Z-index works only when elements overlap, and only on positioned elements.
In Tailwind CSS, z-index is managed through clear, limited utilities to prevent chaos.
When Z-Index Actually Works
Z-index applies only to elements that are:
relative
absolute
fixed
sticky
Z-Index Rule
z-index works only on positioned elements like relative.
<!-- This does nothing -->
<div class="z-10">
No effect
</div>
<!-- This works -->
<div class="relative z-10">
Layered correctly
</div>
Rule:
No position → no z-index effect.
Z-Index Utilities in Tailwind
Tailwind provides a controlled scale:
z-0
z-10
z-20
z-30
z-40
z-50
And:
z-auto
This limited scale is intentional - to avoid random values like z-9999.
Understanding the Z-Index Scale (Layering Strategy)
Think of z-index values as semantic layers, not numbers.
Z-Index Typical Use Case z-0 Base content z-10 Hover elements z-20 Dropdowns z-30 Sticky headers z-40 Modals z-50 Toasts / alerts
- You don’t need more unless building a very complex UI system.
Basic Z-Index
Uses z-index to layer foreground and background elements.
<div class="relative z-10">
Foreground content
</div>
<div class="relative z-0">
Background content
</div>
The element with z-10 appears above z-0.
Modal Layering
Uses z-index to layer a modal above an overlay.
<div class="relative">
<div class="absolute inset-0 bg-black/50 z-10"></div>
<div class="relative z-20 p-6 bg-white">
Modal content
</div>
</div>
This pattern shows:
Overlay layer
Content layer
Clear stacking logic
Z-Index UI Layers
Demonstrates z-index layering for dropdowns, modals, and sticky headers.
<!-- Dropdown Menu -->
<div class="relative">
<button>Menu</button>
<ul class="absolute right-0 mt-2 z-20 bg-white shadow">
<li>Option 1</li>
<li>Option 2</li>
</ul>
</div>
<!-- Modal -->
<div class="fixed inset-0 z-40 bg-black/50"></div>
<div class="fixed inset-0 z-50 flex items-center justify-center">
<div class="bg-white p-6 rounded-lg">
Modal
</div>
</div>
<!-- Sticky Header -->
<header class="sticky top-0 z-30 bg-white">
Navbar
</header>
Stacking Context
Z-index is not global.
Each positioned element can create its own stacking context.Common stacking-context creators:
position + z-index
opacity < 1
transform
filter
backdrop-filter
Stacking Context
Shows how a parent stacking context limits the child z-index.
<div class="relative z-10 opacity-90">
<div class="absolute z-50">
Still trapped inside parent
</div>
</div>
Even with z-50, the child cannot escape its parent’s stacking context.
This is the #1 source of “z-index not working” bugs.
Z-Index vs DOM Order
If two elements have the same z-index, the one later in the DOM appears on top.
Z-Index DOM Order
When z-index is equal, the later element in the DOM appears on top.
<div class="relative z-10">First</div>
<div class="relative z-10">Second (on top)</div>
Z-index + DOM order together determine stacking.
Negative Z-Index
Places the element behind other content using a negative z-index.
<div class="-z-10">
Behind everything
</div>
Use cases:
Decorative backgrounds
Layered visuals
Risks:
Element becomes unclickable
Can disappear behind body
Use only when you fully understand the context.
Z-Index Management Strategy
Instead of random values:
Define layer roles
Reuse the same z-index values everywhere
Treat z-index like a design token system
Example mental model:
Base = 0
UI overlays = 20
Navigation = 30
Modals = 40
Notifications = 50
Consistency prevents bugs.
Common Mistakes
Adding z-index without position
Using extremely large values
Fighting stacking context blindly
Random z-index per component
Debugging visually instead of logically
If z-index “doesn’t work”, the issue is almost always stacking context.
Debugging Z-Index Issues
When something is hidden:
Check if element is positioned
Check parent stacking context
Check opacity/transform/filter on parents
Check competing z-index values
Check DOM order
Accessibility Considerations
Improper z-index can:
Hide focused elements
Block interactions
Trap keyboard navigation
Ensure:
Modals trap focus correctly
Overlays don’t hide focus rings
Important UI stays reachable
Z-index affects usability, not just visuals.