How z-index Works

Although it may not be immediately obvious, the elements in an HTML document are generated in three dimensions. Besides being aligned on the x- and y- axes, elements can lie on the z-axis, which controls their position in the third dimension.

The 3 Dimensions

Properties such as margin, float, and the offset properties control how the element sits on the x- and y- axes. The z-index property solely controls how elements are arranged on this z-axis.

The z-index Property #

The z-index property specifies two things -

The property only applies to positioned elements. That is, elements that have a position of relative, absolute, or fixed.

There are three potential values for the z-index property -

Value Description
auto Sets the stacking level to 0 and does not establish a new stacking context
<integer> Sets the stacking level to the integer and establishes a new stacking context
inherit Sets the stacking level to the same as it’s parent element and does not establish a new stacking context
z-index: auto | <integer> | inherit

Stacking Level #

The stacking level is the value on the z-axis that the current element is on. Higher numbers indicate that the element is higher on the stack of elements and closer to the surface of the screen.

Stacking Level

If not specified by the z-index property, the stacking level of an element is established according to it’s arrangement in the document tree. Elements that are declared later in the document have a higher stacking level by default.

Calculating Stacking Level #

In addition to the specified z-index, the stacking level of an element is controlled by a number of factors. Elements are stacked in the following order.

Position Description CSS
1 (bottom) The element forming the stacking context z-index: <integer>
2 Child elements with negative stack levels `z-index: ``position: relative
3 In-flow, non-inline, non-positioned child elements display: /* not inline */``position: static
4 Non-positioned floating child elements `float: left
5 In-flow inline, non-positioned child elements display: /* inline */``position: static
6 Child elements with stacking level of 0 `z-index: auto
7 (top) Child elements with positive stack levels `z-index: ``position: relative

Stacking Context #

When we specify the stacking level for an element using the z-index property, we are not always specifying the stacking level of the element in relation to every other element on the page. The element’s stacking level is only in relation to its stacking context.

This can lead to some bizarre situations in which an element with a higher number z-index is not always necessarily “above” an element with a lower z-index.

Stacking context can be explained by the following rules.

1. The default stacking context is the root element #

The default stacking context for any HTML document is the root <html> element. Therefore, unless new stacking contexts are created, the stacking level of an element is, by default, in relation to every other element on the page.

2. Establish a new stacking context with the z-index property #

We establish a new stacking context by setting the z-index of an element to any integer. This has the effect of, firstly, setting the current element’s stacking level to that integer, and secondly, creating a new stacking context.

The new stacking context applies to any children of that element. Their stacking levels are now only within that stacking context, not the root stacking context.

In the example below, .foo belongs to stacking context 1, whereas .bar belongs to stacking context 2.

Stacking Context

3. Elements cannot be stacked above (or below) the parent element’s stacking level #

When the parent element’s stacking level is set, that means that its children also cannot be stacked above or below that level (in relation to the parent element's stacking context).

In the example below, even though .bar has a higher z-index than .baz, it still shows "below" it. This is because, in stacking context 1, .bar cannot go above or below stacking level 1.

.foo { z-index: 1; }
.bar { z-index: 1000; }
.baz { z-index: 2; }

Stacking Context

Keep in touch KeepinTouch

Subscribe to my Newsletter 📥

Receive quality articles and other exclusive content from myself. You’ll never receive any spam and can always unsubscribe easily.

Elsewhere 🌐