z-index - Controlling the Stacking Order
The z-index property determines the stacking order of positioned elements. In a 2D browser window, the Z-axis refers to the depth: which element appears closer to the user (on top) and which appears farther away (on the bottom).
Elements with a higher z-index value are placed on top of elements with a lower z-index value.
1. The Core Prerequisite: Positioned Elements
The most common mistake beginners make is trying to use z-index on an element that is not set up correctly.
The z-index property only affects elements that have a position value set to anything other than the default static.
This means z-index works on elements with: position: relative, position: absolute, position: fixed, or position: sticky.
If you apply z-index: 999; to a standard <div> (which is position: static; by default), it will have no effect on its stacking order.
Basic Usage
z-index accepts an integer, which can be positive, negative, or zero.
| Value | Behavior | Example Use |
|---|---|---|
Positive (> 0) | Moves the element closer to the user (on top). | Overlays, modals, fixed headers. |
Zero (0) | Default stacking layer for positioned elements. | Standard content sections. |
Negative (< 0) | Pushes the element behind its parent or other content. | Placing a background image behind text. |
/* This element will be on top of any element with a z-index less than 10 */
.modal-overlay {
position: fixed;
z-index: 100;
}
2. The Advanced Concept: Stacking Context
Understanding the Stacking Context is critical to mastering z-index. A stacking context is like a self-contained environment where z-index rules only apply internally.
When an element establishes a new stacking context, its children are stacked relative to the parent and cannot escape that context.
Why is this important?
Imagine you have two parent elements, A and B, positioned side-by-side:
- Parent A has
z-index: 1. - Parent B has
z-index: 10.
If Parent A has a child element with z-index: 999, this child will NOT appear on top of Parent B. The stacking order is determined by the parents first. Parent B sits on top of Parent A, and everything inside Parent A (including the child with z-index: 999) is constrained to that lower layer.
The z-index of a child element is only meaningful within its own stacking context. It cannot override the stacking order of its parent's siblings.
3. How to Create a Stacking Context
While setting a non-static position (like relative) and any z-index value automatically creates a stacking context, there are other properties that trigger this behavior. This is essential knowledge for advanced layout debugging.
A stacking context is also created by any of the following properties (even if position: static):
opacityless than 1 (e.g.,opacity: 0.99)transform(any value other thannone)filter(any value other thannone)will-change(with values likeopacityortransform)contain: layoutorcontain: paint
If you find an element unexpectedly overlapping something with a higher z-index, check if one of these properties has created an unintended stacking context higher up the tree.
4. Avoiding Pitfalls
Use Low Numbers
Avoid using huge, arbitrary numbers like z-index: 999999. This is known as "z-index stacking wars." Instead, use a structured approach:
- Use
z-index: 1for standard elevated elements. - Use
z-index: 10for high-level UI components (e.g., header, navbar). - Use
z-index: 100for modals or overlays that must cover the entire screen.
Negative z-index Caution
While negative values are useful for putting elements behind their parents, be aware that pushing an element behind the <body> element might hide it completely, as the background layer (often the page background) will cover it.
z-index WarningWhen using z-index: -1, ensure the parent container has a defined background color. If the parent is transparent, the child element might disappear behind the document's main background or behind the browser's scrollbars.
Interactive z-index Demo
Observe how the stacking order is managed by the z-index property on the positioned elements.