CSS Z-index

When positioned elements overlap, z-index decides the front-to-back stacking order, with higher values sitting closer to the viewer.

Web pages are not just flat. Elements can overlap, and z-index controls which one wins that overlap. A higher z-index brings an element toward the front; a lower one pushes it back.

It needs positioning

z-index only affects elements whose position is relative, absolute, fixed, or sticky. On a plain static element it is ignored. See CSS Fixed and Absolute Position for those values.

Layering two boxes

<!DOCTYPE html>
<html>
<head>
<style>
.behind {
  position: absolute;
  z-index: 1;
}
.in-front {
  position: absolute;
  z-index: 2;
}
</style>
</head>
<body>

<div class="behind">Behind</div>
<div class="in-front">In front</div>

</body>
</html>

A typical modal overlay

A common use is putting a dialog above a dimmed backdrop, which in turn sits above the page. Give each layer a clearly separated value so the order is obvious.

Overlay and dialog

<!DOCTYPE html>
<html>
<head>
<style>
.backdrop {
  position: fixed;
  z-index: 100;
}
.dialog {
  position: fixed;
  z-index: 101;
}
</style>
</head>
<body>

<div class="backdrop"></div>
<div class="dialog">
  <p>Are you sure you want to continue?</p>
  <button>Confirm</button>
</div>

</body>
</html>

Stacking contexts

z-index values are only compared within the same stacking context. Certain properties, like a non-default opacity or a transform, create a new context, so a child's huge z-index cannot escape a parent that sits lower.

Note: Avoid enormous values like z-index: 99999. They make conflicts harder to reason about. Plan a small set of layers instead, for example 10, 100, and 1000.
Note: If an element refuses to come to the front despite a high z-index, it is almost always trapped in a parent stacking context. Raise the parent instead.

Exercise: CSS Z-index

What does giving an element a higher z-index value do compared to overlapping elements?