Last updated: March 13, 2026
How to Fix Z-Index Not Working in CSS
Complete troubleshooting guide for z-index issues. Learn about stacking contexts, position requirements, and common gotchas that break z-index.
Why Is Z-Index So Confusing?
z-index seems simple: higher numbers go in front, right? But it's one of the most frustrating CSS properties because it has hidden rules. The key concept is stacking contexts - invisible boundaries that control how z-index actually works.
This guide covers the most common z-index problems and their solutions, from missing position properties to parent stacking contexts trapping your elements.
Common Causes
Before diving into solutions, here are the typical reasons why z-index doesn't work as expected.
No Position Property Set
z-index only works on positioned elements. If your element has position: static (the default), z-index is ignored.
Parent Creates New Stacking Context
If a parent element creates a stacking context (via position + z-index, opacity, transform, etc.), children can't escape it.
Transform or Other Properties
Properties like transform, filter, perspective, and will-change create new stacking contexts, isolating z-index values.
Competing with Wrong Siblings
Elements only compete with their siblings in the same stacking context. Check if you're comparing the right elements.
Solutions
Solution 1: Add Position Property
Problem
Your element has z-index but no position property, so z-index is being ignored.
Before (Not Working)
.element {
z-index: 999;
/* position is missing! */
}After (Fixed)
.element {
position: relative; /* or absolute, fixed, sticky */
z-index: 999;
}Why This Works
z-index only works on positioned elements. Adding position: relative is usually the safest choice as it keeps the element in the normal document flow while enabling z-index. Use absolute or fixed if you need the element removed from the flow.
Solution 2: Understand Stacking Contexts
Problem
Your element has z-index: 9999 but still appears behind another element with z-index: 1 because they're in different stacking contexts.
Before (Not Working)
<div class="parent"> <!-- Creates stacking context -->
<div class="child">z-index: 9999</div>
</div>
<div class="other">z-index: 1</div>
.parent {
position: relative;
z-index: 0; /* Creates stacking context */
}
.child {
position: relative;
z-index: 9999; /* Trapped inside parent! */
}
.other {
position: relative;
z-index: 1; /* Wins because parent has z-index: 0 */
}After (Fixed)
.parent {
position: relative;
z-index: 2; /* Increase parent's z-index */
}
.child {
position: relative;
z-index: 9999; /* Now parent is above .other */
}
.other {
position: relative;
z-index: 1;
}Why This Works
When a parent creates a stacking context, children compete only with each other, not with elements outside. The parent's z-index determines the group's position. To fix this, adjust the parent's z-index, not the child's.
Solution 3: Remove Transform from Parent
Problem
A parent element has transform, which creates a stacking context and traps children's z-index values.
Before (Not Working)
.parent {
transform: translateX(0); /* Creates stacking context! */
}
.child {
position: relative;
z-index: 999; /* Can't escape parent's context */
}After (Fixed)
/* Option 1: Remove transform */
.parent {
/* transform: translateX(0); - removed */
}
.child {
position: relative;
z-index: 999; /* Now works! */
}
/* Option 2: Move transform to wrapper */
.wrapper {
transform: translateX(0);
}
.parent {
/* No transform here */
}
.child {
position: relative;
z-index: 999;
}Why This Works
Transform creates a stacking context even without z-index. If you need the transform, consider applying it to a wrapper element instead, or adjusting your HTML structure so the stacking context doesn't interfere with your z-index needs.
Solution 4: Use Negative Z-Index Correctly
Problem
You're trying to use z-index: -1 to put an element behind content, but it's disappearing behind the page background.
Before (Not Working)
.background {
position: absolute;
z-index: -1; /* Disappears! */
}After (Fixed)
.container {
position: relative;
z-index: 0; /* Creates stacking context */
}
.background {
position: absolute;
z-index: -1; /* Now behind content but visible */
}
.content {
position: relative;
z-index: 1; /* In front of background */
}Why This Works
Negative z-index places elements behind their stacking context. If you want an element behind content but still visible, create a stacking context on the parent with z-index: 0. This keeps negative z-index elements inside that context, preventing them from going behind the page.
Solution 5: Check for Other Stacking Context Properties
Problem
Your z-index isn't working because a parent has opacity, filter, or other properties that create stacking contexts.
Before (Not Working)
.parent {
opacity: 0.99; /* Creates stacking context! */
}
.child {
position: relative;
z-index: 999; /* Trapped inside */
}After (Fixed)
/* Remove the stacking context property */
.parent {
/* opacity: 0.99; - removed or moved */
}
.child {
position: relative;
z-index: 999; /* Now works freely */
}
/* Or adjust parent's z-index */
.parent {
opacity: 0.99;
position: relative;
z-index: 10; /* Raise entire group */
}Why This Works
Many CSS properties create stacking contexts: opacity < 1, filter, mix-blend-mode, isolation: isolate, will-change: transform/opacity, and more. Use DevTools to identify if a parent has these properties, then either remove them, move them to a different element, or adjust the parent's z-index.
Quick Troubleshooting Checklist
When z-index isn't working, run through this checklist to identify the issue.
Does the element have a position property?
position: relative, absolute, fixed, or sticky is required
Is there a parent with a stacking context?
Check parents for position + z-index, opacity, transform, filter, etc.
Are you comparing elements in the same stacking context?
Elements only compete with siblings in the same context
Is the z-index value high enough?
Compare with siblings' z-index values, not unrelated elements
Does DevTools show the z-index is applied?
Check computed styles - if it's not there, position is missing
Properties That Create Stacking Contexts
These CSS properties create new stacking contexts, which can trap z-index values. Watch out for them on parent elements.
position + z-index (not auto)opacity < 1transform (any value except none)filter (any value except none)perspective (any value except none)clip-path (any value except none)mask / mask-image / mask-bordermix-blend-mode (not normal)isolation: isolatewill-change: opacity, transform-webkit-overflow-scrolling: touchcontain: layout, paint, or strictFrequently Asked Questions
The most common reason z-index doesn't work is that the element doesn't have a position property set. z-index only works on positioned elements (position: relative, absolute, fixed, or sticky). If your element has position: static (the default), z-index will be ignored.
A stacking context is a three-dimensional conceptualization of HTML elements along the z-axis. Elements with certain CSS properties (like position + z-index, opacity < 1, transform, or filter) create a new stacking context. Elements inside a stacking context can only compete with their siblings - they can't escape their parent's stacking order.
Yes, negative z-index values are valid and useful. z-index: -1 will place an element behind its parent (if the parent has z-index: 0 or auto). This is commonly used for background decorative elements that should appear behind content but still be part of the DOM for animation purposes.
Yes, applying transform creates a new stacking context, even without z-index. This means an element with transform will isolate its children's z-index from the rest of the page. Children can't use z-index to appear above elements outside their transformed parent's stacking context.
Use browser DevTools to inspect the element and check: 1) Does it have a position property? 2) Is there a parent with a stacking context? 3) Are siblings also positioned? You can also use Frontend Hero's CSS Scanner to quickly see all z-index values and stacking contexts on a page.
More CSS Tutorials
Copy CSS from Website
Extract styles with 2 clicks
Center a Div (CSS)
Flexbox, Grid, and more
Center a Div (Tailwind)
Utility classes for centering
Convert CSS to Tailwind
CSS to utility classes
Glassmorphism Effect
Frosted glass UI style
Neumorphism Button
Soft UI button design
Responsive Navbar
Mobile-friendly navigation
Sticky Header
Fixed navigation on scroll
CSS Pagination
Page navigation styles
CSS Accordion
Expandable content sections
Dropdown Menu
Hover and click dropdowns
CSS Modal
Popup dialog boxes
Toast Notifications
Animated alert messages
Hamburger Menu
Animated menu icon
Animate Gradients
Moving gradient backgrounds
Skeleton Loader
Loading placeholder UI
Element Screenshot
Capture any element as image
Pick Color from Website
Eyedropper tool comparison
Identify Fonts
Find fonts on any website
Download All Images
Bulk save images from any site
Measure Elements
Page ruler and measurements
Extract Colors from Website
Get any color palette instantly
Dark Mode Toggle
CSS variables and localStorage
Responsive Grid
CSS Grid auto-fit and minmax
Center Text in CSS
text-align, Flexbox, and Grid
Make Text Bold
font-weight values explained
Add Shadow in CSS
box-shadow, text-shadow, drop-shadow
Round Corners in CSS
border-radius and pill shapes
Style File Input
Custom upload buttons
