Describe `z-index` and how stacking context is formed.
TL;DR
z-index orders a box only within its current stacking context; it is not a global page-wide height. A stacking context is painted as one atomic unit in its parent, so a descendant with z-index: 9999 cannot escape an ancestor that is below a sibling context. Positioned elements with a non-auto z-index, flex or grid items with a non-auto z-index, transforms, opacity below 1, containment, and several other features create contexts. Elements in the browser's top layer, such as an open modal <dialog>, are above ordinary document stacking contexts.
Describe z-index and how stacking context is formed.
When boxes overlap, CSS applies a defined painting order. z-index influences that order for positioned boxes and for flex and grid items, but its values are compared only among relevant siblings in the same stacking context.
Why a large z-index can still lose
<div class="page-header">Header</div><main class="content"><div class="tooltip">Tooltip</div></main>
.page-header {position: relative;z-index: 2;}.content {position: relative;z-index: 1;transform: translateZ(0);}.tooltip {position: absolute;z-index: 9999;}
The tooltip remains below the header because the entire .content context is at level 1, below the header at level 2. Increasing the tooltip's value cannot move it into the header's parent context. Fix the context structure or render the overlay in an appropriate shared layer rather than escalating arbitrary numbers.
Common stacking-context triggers
Common examples include:
- The root element.
position: absoluteorrelativewithz-indexother thanauto.position: fixedorsticky.- A flex or grid item with
z-indexother thanauto. opacityless than1.- A non-
nonetransform,filter,perspective, mask, or blend mode. - Relevant
isolation,contain,container-type, andwill-changevalues.
The full list evolves with CSS features, so use the browser's stacking-context inspection rather than memorizing only a few triggers. Also distinguish stacking contexts from compositing layers: a browser may promote content to a GPU layer as an implementation optimization, but that does not redefine CSS painting order.
For application overlays, use a small documented layer scale and native top-layer APIs such as <dialog> or popovers where their behavior fits the interaction.