Z-index is a CSS property that controls the stacking order of overlapping HTML elements on a web page. When elements are positioned (using relative, absolute, fixed, or sticky positioning), the z-index determines which element appears in front of or behind others along the z-axis, the imaginary axis that extends perpendicular to the screen toward the viewer. Elements with higher z-index values are rendered on top of elements with lower values.
While the concept seems straightforward, z-index is one of the most commonly misunderstood properties in CSS. Its behavior is governed by stacking contexts, isolated layers within which z-index values are compared. A new stacking context is created by various CSS properties, including:
- Elements with a
positionvalue other thanstaticand a z-index value other thanauto - Elements with
opacityless than 1 - Elements with
transform,filter, orperspectiveproperties - Flex and grid children with a z-index value other than
auto
A common pitfall is setting increasingly large z-index values (like 9999 or 999999) to force elements on top, without understanding that z-index comparisons only work within the same stacking context. A child element with z-index: 9999 inside a parent with z-index: 1 will still appear behind a sibling of that parent with z-index: 2. Understanding stacking contexts is key to mastering z-index.
For front-end developers building complex user interfaces with modals, dropdown menus, tooltips, sticky headers, and notification overlays, proper z-index management is critical. Best practices include establishing a z-index scale (using CSS custom properties or design tokens) and documenting stacking context hierarchies to keep UI layers clean and maintainable.