A stacking context is a group of elements that the browser layers as one unit. Think of it as a folder of layers. z-index only sorts the layers inside one folder. Then the whole folder is placed among the other folders as a single item.
So z-index only orders an element against siblings in the same stacking context. Once a parent forms its own context, all its children are painted together at the parent's level. That is why z-index: 9999 on a child can never lift it above something that beats the parent.
These create a stacking context, among others:
- the root element
- positioned elements with a
z-indexother thanauto fixedandstickyelements- flex and grid items with a
z-index opacitybelow 1transformfilterisolation: isolatemix-blend-modewill-changefor any of those properties
Other common reasons why z-index seems broken:
z-indexon astaticelement is ignored, except on flex and grid items.- An ancestor with
overflow: hiddenclips the element.
To fix it, raise the ancestor instead, or move the element. For example, render it into a portal at the end of body. A portal shows a component in a different place in the DOM from where you wrote it.
z-indexonly compares elements inside one stacking context.- Children are trapped at their parent's level, like layers inside one folder.
- Stacking contexts are created by positioned elements with a
z-index,opacitybelow 1,transform,filter,isolationand more. z-indexis ignored onstaticelements that are not flex or grid items.