Skip to content

z-index and stacking contexts

When we change the position value to anything other than static, we enable the z-index property. We can also use z-index on Grid and Flex Items without having to change the position value of them.

z-index seems simple at first, but it often becomes a headache because people don’t understand stacking contexts, and as soon as we start using positioning and z-index, stacking contexts become a thing.

Luckily, it’s pretty easy to understand how it works, and once you understand it, stacking elements becomes very easy.

To use z-index, an element either needs to have a position other than static, or be a grid or flex item.

At it’s core, z-index is very simple. The only values we can use are unitless numbers. The bigger the number, the higher the element is in the stack.

.not-too-high {
position: relative;
z-index: 2;
}
.on-top-of-the-previous-selector {
position: relative;
z-index: 10;
}
.very-high-up {
position: fixed;
z-index: 9999;
}
.under-everything {
z-index: -1;
}

Stacking contexts are a part of what I call the unknown fundamentals of CSS (along with containing blocks) because they don’t get nearly enough attention.

When we use z-index, elements are stacked based on the biggest number, but below I have an example where an element with a z-index: 2 is above an element with a z-index: 9999, which doesn’t seem like it should be possible.

The reason for this is that the element with the z-index: 9999 is in another element with a z-index: 1. That element has created a new stacking context, so the 9999 is only relative to other elements inside of that specific context. It can’t escape out, and jump ahead of other elements in different stacking contexts.

The MDN has a full list of what creates a new stacking context. It’s a long list, but don’t worry too much about it. The main thing I want you to think about is if you run into an issue with stacking, remember the concept of stacking contexts. Knowing that is a thing, you can then dig into what the actual cause might be.

As the list above shows, there are a lot of things that create new stacking contexts. Only one of them creates one without any side effects.

.new-stacking-context {
isolation: isolate;
}

Knowing about stacking contexts means that you can make new ones on purpose, and avoid strange problems that can arise!