Skip to main content

What is Z-Index?

Z-index is a CSS property that controls the stacking order of overlapping elements. Higher values appear in front of lower values -- but only when you understand stacking contexts.

TL;DR

  • 1.z-index sets the front-to-back order of overlapping elements. Higher numbers go in front.
  • 2.z-index only works on positioned elements (relative, absolute, fixed, or sticky).
  • 3.Stacking contexts create invisible boundaries -- elements inside one cannot escape their parent's layer.
  • 4.Properties like transform, opacity, and filter silently create stacking contexts.

Simple Explanation

Imagine a stack of papers on your desk. The paper on top covers the ones below it. z-index is the number you write on each paper to decide which one goes on top.

But here's the catch: if you put some papers inside a folder, those papers can only be rearranged within the folder. The folder itself has one position in the stack. That folder is a stacking context.

This is why setting z-index: 9999 sometimes doesn't work -- the element is inside a "folder" (stacking context) that has a lower position than what you're trying to cover.

How It Works

z-index requires a position property. Without it, the browser ignores z-index entirely.

Basic z-index stacking

.behind {
  position: relative;
  z-index: 1;
}

.in-front {
  position: relative;
  z-index: 2;  /* Appears on top */
}
z-index: 1
z-index: 2

Modal overlay pattern

.overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.5);
  z-index: 50;
}

.modal {
  position: fixed;
  z-index: 51;  /* Above the overlay */
}

Recommended z-index scale

:root {
  --z-dropdown: 10;
  --z-sticky:   20;
  --z-overlay:  30;
  --z-modal:    40;
  --z-popover:  50;
  --z-tooltip:  60;
}

Using CSS custom properties with a predictable scale prevents z-index wars where developers keep adding larger numbers.

Properties That Create Stacking Contexts

These CSS properties create new stacking contexts, which can trap z-index values inside them.

position + z-index (not auto)
opacity less than 1
transform (any value)
filter (any value)
perspective (any value)
isolation: isolate
mix-blend-mode (not normal)
will-change: transform or opacity
contain: layout, paint, or strict

Common Mistakes

Don't

/* Missing position property */
.element {
  z-index: 999;
  /* Won't work without position! */
}

Do

.element {
  position: relative;
  z-index: 999;
}

Don't

/* z-index arms race */
.dropdown { z-index: 999; }
.modal    { z-index: 9999; }
.tooltip  { z-index: 99999; }

Do

/* Use a predictable scale */
.dropdown { z-index: 10; }
.modal    { z-index: 40; }
.tooltip  { z-index: 60; }
Frontend Hero

Debug stacking contexts on any website

Frontend Hero's CSS Scanner shows z-index, position, and stacking context for any element. Stop guessing which parent is trapping your layers.

Try CSS Scanner

Browser Support

z-index is supported in all browsers since CSS2 (1998). There are no compatibility concerns. The stacking context rules also work consistently across all modern browsers.

Frequently Asked Questions

Why does z-index: 9999 not work?

A very high z-index doesn't help if the element is trapped inside a stacking context. When a parent creates a stacking context (via position + z-index, transform, opacity < 1, etc.), its children can only compete with each other -- not with elements outside the parent. You need to raise the parent's z-index instead.

Does z-index work without position?

No. z-index only applies to positioned elements -- those with position: relative, absolute, fixed, or sticky. If an element has position: static (the default), z-index is completely ignored. This is the most common reason z-index 'doesn't work.'

What is a stacking context?

A stacking context is an invisible boundary that groups elements for z-index purposes. Think of it as a folder -- elements inside the folder can be reordered, but the folder itself has a single position in the stack. Stacking contexts are created by position + z-index, opacity < 1, transform, filter, isolation: isolate, and several other properties.

Can z-index be negative?

Yes. Negative z-index (e.g., z-index: -1) places an element behind its stacking context's background. This is useful for decorative background layers. Make sure the parent creates a stacking context (e.g., with position: relative; z-index: 0) so the negative-index child doesn't disappear behind the page root.

What is the maximum z-index value?

The maximum z-index is 2,147,483,647 (the max 32-bit integer). In practice, you should never need values that high. A well-organized z-index scale uses low, predictable numbers -- for example: 1 for overlays, 10 for dropdowns, 50 for modals, 100 for tooltips.