CSS Z-index
In this page:
selector {
position: relative;
z-index: integer;
}
The Virtual Z-Axis Stack
Webpages are rendered in three dimensions. The X-axis handles horizontal layout, the Y-axis handles vertical content flow, and the Z-axis handles stacking depth. The z-index property determines where positioned elements sit along this virtual stacking layer.
- Use z-index to manage overlapping cards, floating alerts, and layout blocks cleanly.
- Accepted values:
- integer — any whole number, positive or negative, e.g. 10
- auto — uses the parent's stacking order (default)
- Only works on positioned elements or flex and grid items
- inherit | initial | unset | revert — CSS-wide keywords accepted by every property
Example: The Virtual Z-Axis Stack
<style>
.wrapper {
position: relative;
min-height: 100px;
}
.back {
position: absolute;
top: 10px;
left: 10px;
width: 140px;
height: 80px;
background: gray;
color: white;
z-index: 1;
}
.front {
position: absolute;
top: 30px;
left: 40px;
width: 140px;
height: 80px;
background: tomato;
color: white;
z-index: 2;
}
</style>
<div class="wrapper">
<div class="back">Behind on the Z-axis</div>
<div class="front">In front on the Z-axis</div>
</div>
Requires Positioned Elements
A common point of confusion is why a z-index property is not working. Z-index will only work on positioned elements (elements with a position of relative, absolute, fixed, or sticky). It is ignored on statically positioned elements.
- If a z-index rule is not working, make sure the element has a position other than static.
- Accepted values:
- auto — follows the order in the document (initial value)
- integer — e.g. 1, 10, 999
- negative integer — behind siblings
- 0 — creates a stacking context on positioned elements
- inherit | initial | unset | revert — CSS-wide keywords accepted by every property
Example: Requires Positioned Elements
<style>
.ignored {
z-index: 999;
background: gray;
color: white;
padding: 10px;
margin-bottom: 10px;
}
.works {
position: relative;
z-index: 999;
background: crimson;
color: white;
padding: 10px;
}
</style>
<div class="ignored">z-index ignored (position: static)</div>
<div class="works">z-index works (position: relative)</div>
Understanding Stacking Contexts
Z-index layers do not operate globally. They are limited within parent elements that form a 'Stacking Context'. An element with a z-index of 999 nested inside a parent with a z-index of 1 can still sit behind an element with a z-index of 2 on the main page structure.
Example: Understanding Stacking Contexts
<style>
.parent {
position: relative;
z-index: 1;
background: #eef;
padding: 10px;
min-height: 100px;
}
.child {
position: relative;
z-index: 999;
top: 20px;
background: crimson;
color: white;
padding: 8px;
display: inline-block;
}
.sibling {
position: relative;
z-index: 2;
top: -20px;
left: 20px;
background: seagreen;
color: white;
padding: 8px;
display: inline-block;
}
</style>
<div class="parent">
<div class="child">z-index 999, but trapped inside the parent's stacking context</div>
</div>
<div class="sibling">z-index 2, still stacks above the parent above</div>
Standardizing Stacking Order Guides
As websites grow, managing z-index values can become messy. Creating a standardized z-index reference guide (like using increments of 10 or 100) helps prevent styling conflicts and keeps layouts clean.
Example: Standardizing Stacking Order Guides
<style>
.header {
position: relative;
z-index: 100;
background: steelblue;
color: white;
padding: 10px;
}
.modal {
position: relative;
z-index: 200;
top: -20px;
left: 20px;
background: crimson;
color: white;
padding: 10px;
}
</style>
<div class="header">Layer 100</div>
<div class="modal">Layer 200</div>
Implicit Stacking with opacity and transform
Z-index coordinates can sometimes trigger without explicit z-index rules. Properties like opacity (less than 1.0), transform, or filter automatically create new stacking contexts natively, which can affect element layering.
Example: Implicit Stacking with opacity and transform
<style>
.box {
opacity: 0.99;
transform: translateZ(0);
background: steelblue;
color: white;
padding: 10px;
display: inline-block;
}
</style>
<div class="box">Creates a new stacking context without an explicit z-index</div>
- Applying z-index values to statically positioned elements, which is ignored by browsers.
- Using negative z-index values on text blocks, pushing them behind background containers.
- Using arbitrary z-index values like 99999, causing rendering conflicts in larger layouts.
- The z-index property determines the horizontal stacking layers of overlapping elements along the Z-axis.
- Z-index rules are ignored on statically positioned elements; ensure elements have a relative, absolute, fixed, or sticky position.
- Layer coordinates are confined within parental 'Stacking Contexts'; manage parent container z-index values to resolve conflicts.
Standard z-index layers and stacking context triggers are supported natively by all modern web browsers.
Chapter Quiz — Complete all 14 topics to unlock
0/14 topics done
Complete these topics first: