← Back to CSS Course | Chapter 5: Layout & Display | Lesson 6 of 14

CSS Z-index

Imagine stack of papers on your desk. Each paper represents a box on your webpage. By default, the paper you place last sits on top of the others. If you want to pull an older paper to the top, you change its priority. CSS z-index is that priority order. It controls the vertical stacking layer of overlapping elements along the virtual Z-axis (pointing toward or away from your screen). By assigning z-index values, you can control which cards, sidebars, alerts, or popup modals sit on top, and which ones stay layered in the background.

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.

Note: Use z-index to manage overlapping cards, floating alerts, and layout blocks cleanly.

Warning: Z-index values can be positive or negative, but negative values can push elements behind background container backgrounds, making them unclickable.

Example: The Virtual Z-Axis Stack

css
<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.

Note: If a z-index rule is not working, make sure the element has a position other than static.

Warning: Adding position: relative to an element just to enable z-index is safe, but be careful not to introduce accidental offsets.

Example: Requires Positioned Elements

css
<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.

Note: Think of stacking contexts like folders: everything inside folder 1 stays behind folder 2, regardless of internal index numbers.

Warning: Creating nested stacking contexts can make debugging overlapping elements in complex layouts difficult.

Example: Understanding Stacking Contexts

css
<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.

Note: Organize your z-index values into structured layers (e.g., header: 100, modal: 200) to keep your stylesheet rules clean.

Warning: Avoid using arbitrary z-index values like 99999, as they can cause rendering bugs and conflicts.

Example: Standardizing Stacking Order Guides

css
<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.

Note: If elements are stacking unexpectedly, check if properties like transform are creating new stacking contexts.

Warning: Applying opacity to a container can push all its nested elements behind adjacent content layers on the page.

Example: Implicit Stacking with opacity and transform

css
<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>
Common Mistakes
  1. Applying z-index values to statically positioned elements, which is ignored by browsers.
  2. Using negative z-index values on text blocks, pushing them behind background containers.
  3. Using arbitrary z-index values like 99999, causing rendering conflicts in larger layouts.
Chapter Summary
  • 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.
Browser Support

Standard z-index layers and stacking context triggers are supported natively by all modern web browsers.

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.