Skip to main content
CalcChef

Z-Index Stacking Context Debugger

Check which CSS properties make an element a stacking context (position, z-index, opacity, transform, isolation) and where its z-index counts. How it works

Use the Z-Index Stacking Context Debugger

CSS selector identifying the element (e.g., #header, .modal, div.container)

auto, or a whole number from -1,000,000 to 1,000,000

z-index of the nearest ancestor that creates a stacking context, or auto when there is none

Flex or grid item (z-index applies even when static)
Isolation: isolate (creates a stacking context)
Creates a stacking context
Yes

Why it creates a stacking context

  • position: relative with z-index 0 (a non-auto z-index on a positioned box)

Debug Explanation

#element creates its own stacking context because position: relative with z-index 0 (a non-auto z-index on a positioned box). Its children are ordered only among themselves. The element itself is ordered in its ancestor context by its z-index (0).

Stacking path

  1. 1. Root (HTML) context
  2. 2. This element (z-index 0)

Elements are compared level by level from the root down. Inside one context only the z-index of its members counts.

Stacking Context Root

#element (its own context)

Painting order inside its ancestor context

  1. Negative z-index positioned descendants
  2. Block-level descendants
  3. Floats
  4. Inline-level descendants
  5. Positioned descendants with z-index auto or 0 (this element)
  6. Positive z-index positioned descendants

Rules used

  • A positioned element with a z-index other than auto creates a stacking context.
  • position: fixed and sticky create one; z-index auto on absolute or relative creates none.
  • z-index also applies to flex and grid items; a static element that forms a context only through opacity, transform or isolation is painted in the z-index 0 layer.
  • opacity below 100% and transform other than none create one.
  • Within a context, z-index orders elements; a context is painted as one unit in its parent.
  • This list is not exhaustive. Other properties, such as filter, also create contexts.

About the Z-Index Stacking Context Debugger

An element with position: relative and z-index: 0 forms a stacking context; with z-index: auto it does not. This debugger checks one element’s position, z-index, ancestor z-index, opacity, transform and isolation, says whether it forms a stacking context and why, shows its stacking path from the root and marks its painting layer. Triggers it does not model, such as filter, are named on the page.

Which settings form a stacking context in this tool

SettingsForms a contextz-index appliesLayer
relative, z-index autoNoYesz-index 0 or auto layer
relative, z-index 0YesYesz-index 0 or auto layer
relative, z-index -1YesYesNegative z-index layer
absolute, z-index autoNoYesz-index 0 or auto layer
absolute, z-index 5YesYesPositive z-index layer
fixed, z-index autoYesYesz-index 0 or auto layer
sticky, z-index autoYesYesz-index 0 or auto layer
static, z-index 5NoNonone
static, flex or grid item, z-index 5YesYesPositive z-index layer
static, opacity 99%YesNoz-index 0 or auto layer
static, transform translate3dYesNoz-index 0 or auto layer
static, isolation: isolateYesNoz-index 0 or auto layer

What the tool reports with the other fields at their defaults (opacity 100%, transform none, isolation off, ancestor context z-index auto, not a flex or grid item unless stated). Layer is the painting layer inside the ancestor context. A static element that forms a context only through opacity, a transform or isolation is painted in the z-index 0 layer without using its z-index.

How to use this tool

  1. Enter the element’s position and z-index (auto or a whole number from -1,000,000 to 1,000,000).
  2. Enter the z-index of its nearest ancestor that forms a stacking context, or auto when there is none.
  3. Set opacity, transform and isolation if the element or its styles use them, and tick Flex or grid item if it is one.
  4. Read whether it forms a stacking context, the stacking path and the painting layer.

Frequently asked questions

Why is my z-index not working?
Three causes are common. The element is static, so its z-index has no effect (MDN says z-index applies to positioned elements and to flex and grid items). Its ancestor forms a stacking context with a lower z-index than the element you want it to cover. Or an ancestor’s opacity, transform or position forms a context you did not intend. The tool’s stacking path shows the levels.
Why does z-index 9999 not win over another element?
Elements are compared level by level from the root. A child with z-index 10 inside an ancestor context with z-index 2 is compared with other elements at level 2 first, so it loses to any sibling context at z-index 3. The tool shows that path: Root context, ancestor context (z-index 2), this element (z-index 10).
What creates a stacking context in CSS?
MDN lists the root element, position absolute or relative with a z-index other than auto, position fixed or sticky, opacity below 1, a transform other than none, isolation: isolate, a flex or grid item with a z-index other than auto, and more, including filter, perspective, mix-blend-mode, will-change and contain. This tool models position, z-index, opacity, transform, isolation and a flex or grid item with a z-index only. Its Transform menu lists translate3d, rotate3d and scale3d, but any transform other than none, including 2D ones such as translateX() or rotate(), forms a context the same way, so pick any of the three for those.
Does opacity create a stacking context?
Yes, any value below 1. The CSS Color specification says a box with opacity less than 1 forms a stacking context for its children. The tool treats any opacity below 100% as one.
How do I find which ancestor creates a stacking context on my page?
Select the element in your browser’s developer tools (Elements panel), open the Console and paste the line below. $0 is the selected element; the line walks up its ancestors and prints each one’s position, z-index, opacity, transform and isolation, whether it is a flex or grid item, and which of the MDN triggers make it a stacking context, including filter, mix-blend-mode, contain and container-type. Copy the values of the element and its nearest context into the fields here. It runs only in your own tab, and it does not detect the top layer (popovers, fullscreen) or keyframe animations. for (let el = $0; el; el = el.parentElement) { const s = getComputedStyle(el), item = !!el.parentElement && /flex|grid/.test(getComputedStyle(el.parentElement).display), why = []; if (el === document.documentElement) why.push('root'); if (/absolute|relative/.test(s.position) && s.zIndex !== 'auto') why.push('position + z-index'); if (/fixed|sticky/.test(s.position)) why.push(s.position); if (item && s.zIndex !== 'auto') why.push('flex or grid item + z-index'); if (parseFloat(s.opacity) < 1) why.push('opacity'); if (s.mixBlendMode !== 'normal') why.push('mix-blend-mode'); for (const k of ['transform', 'scale', 'rotate', 'translate', 'filter', 'backdropFilter', 'perspective', 'clipPath', 'maskImage']) if (s[k] && s[k] !== 'none') why.push(k); if (s.isolation === 'isolate') why.push('isolation'); if (/layout|paint|strict|content/.test(s.contain)) why.push('contain'); if (/size/.test(s.containerType)) why.push('container-type'); if (s.willChange !== 'auto') why.push('will-change (check it)'); console.log(el.tagName.toLowerCase() + (el.id ? '#' + el.id : ''), '| position ' + s.position, '| z-index ' + s.zIndex, '| opacity ' + s.opacity, '| transform ' + s.transform, '| isolation ' + s.isolation, item ? '| flex or grid item' : '', '| ' + (why.length ? 'forms a stacking context: ' + why.join(', ') : 'no stacking context')); }
Does position: fixed need a z-index to form a context?
No. MDN lists position fixed and sticky as forming a stacking context on their own, and the tool reports them that way.

Related Tools

View all tools