Understanding Stacking Context and Z-index

a89529294

Albert Chang

Posted on March 15, 2022

Understanding Stacking Context and Z-index

What are they?

You can think of stacking context as a container that determines how the direct* children are ordered along the z axis(positive direction pointing towards the user). Z-index is used to change the default orders.

*Note that direct/first level children are from the point of view of stacking contexts not the DOM. So if we have the following structure html -> div -> div -> span, both divs and the span are siblings as long as the divs do not create additional stacking contexts.

Why should we care?

Usually when elements are not overlapping each other it does not matter who is actually further along the z axis. But often we have elements such as header, footer or modal that will overlap other elements.

How are stacking contexts created?

The following are the most common ways to create stacking contexts:

  1. html element by default creates one.
  2. position:absolute; and position:relative; with z-index set to anything other than auto.
  3. position:fixed; and position:sticky;
  4. grid and flex items with z-index set to anything other than auto.
  5. Setting isolation:isolate;.
  6. Setting opacity to less than 1.

For a full list check MDN Stacking Context

How are direct children actually positioned in a stacking context?

  1. The stacking context container gets placed first.
  2. Elements with negative z-index.
  3. Elements with no z-index or z-index that is invalid on that element.
  4. Elements with z-index:auto, z-index:0, or positioned elements with no explicit z-index.
  5. Elements with positive z-index;
z-index is only valid on positioned elements and flex/grid items.
Elements within the same category are ordered following the DOM order.

Examples

Note unless otherwise specified, the elements do not create stacking contexts.

  • html(default stacking context)
    • div1
      • div2
      • div3
      • div4
        • span

In this situation, div1, div2, div3, div4, span are all direct children of the stacking context created by html. So they are all category 3 elements from above section and will be ordered following the DOM order.

  • html(default stacking context)
    • div1
      • div2(position:relative; z-index:1;)
        • div3(position:absolute; z-index:9999;)
    • div4(position:relative; z-index:2;)

In this situation, we have 4 stacking contexts. Since only 2 of them, html and div2 have children we don't need to worry about the other 2.
From the pov of the html stacking context, it has three direct children, div1, div2, and div4, and their order along the z axis is the same. This means that despite div3 having a high z-index it will be below div4 since it is contained within a parent(div2) that is rendered below div4.

Summary

Understanding how z-index and how it orders elements along the z axis is all about understanding what stacking context the elements are in and knowing that you can only compare direct children with each other in a stacking context.

💖 💪 🙅 🚩
a89529294
Albert Chang

Posted on March 15, 2022

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related