Skip to main content
Practice Problems

CSS z-index and stacking context

What is z-index?

z-index controls the stacking order of positioned elements along the z-axis (depth). Higher values appear in front of lower values.


Basic Usage

css
.behind { position: relative; z-index: 1; } .in-front { position: relative; z-index: 2; /* Appears above .behind */ }

Key rule: z-index only works on elements with a position value other than static (i.e., relative, absolute, fixed, or sticky), or on flex/grid children.

What is a Stacking Context?

A stacking context is a three-dimensional conceptual container that determines how child elements are stacked. Children are isolated — their z-index only competes with siblings in the same stacking context.

What Creates a Stacking Context?

Property/ConditionExample
Root element<html>
position + z-index (not auto)position: relative; z-index: 1;
opacity < 1opacity: 0.99;
transform (any value)transform: translateX(0);
filter (any value)filter: blur(0);
will-changewill-change: transform;
isolation: isolateExplicitly creates a context
position: fixed or stickyAlways creates a context
Flex/Grid child with z-indexz-index: 1; on flex child

The Classic z-index Problem

html
<div class="parent-a" style="position: relative; z-index: 1;"> <div class="child" style="position: relative; z-index: 9999;"> I have z-index: 9999 but I'm trapped! </div> </div> <div class="parent-b" style="position: relative; z-index: 2;"> I appear ABOVE child despite z-index: 2 </div>

The child with z-index: 9999 can never appear above parent-b because its parent (parent-a) has a lower z-index. The child's stacking is isolated within parent-a.

isolation: isolate

isolation: isolate creates a new stacking context without side effects:

css
.modal-container { isolation: isolate; /* New stacking context, clean */ } .modal { position: fixed; z-index: 100; }

Best Practices

Use z-index Scale

css
:root { --z-dropdown: 100; --z-sticky: 200; --z-overlay: 300; --z-modal: 400; --z-popover: 500; --z-tooltip: 600; --z-toast: 700; } .modal { z-index: var(--z-modal); } .tooltip { z-index: var(--z-tooltip); } .dropdown { z-index: var(--z-dropdown); }

Avoid z-index Wars

css
/* ❌ Bad */ .header { z-index: 99999; } /* ✅ Good — use organized scale */ .header { z-index: var(--z-sticky); }

Debugging z-index

  1. Open browser DevTools
  2. Inspect the element and check its z-index
  3. Walk up the DOM to find parent stacking contexts
  4. Check if any ancestor has opacity, transform, filter, or will-change — these silently create stacking contexts

Important:

Most z-index issues stem from not understanding stacking contexts. Remember: a child can never escape its parent's stacking context. Use isolation: isolate to create controlled stacking contexts and organize z-index values with CSS custom properties.

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.

Finished reading?
Practice Problems