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:
-
html
element by default creates one. -
position:absolute;
andposition:relative;
withz-index
set to anything other thanauto
. -
position:fixed;
andposition:sticky;
-
grid
andflex
items withz-index
set to anything other thanauto
. - Setting
isolation:isolate;
. - Setting
opacity
to less than 1.
For a full list check MDN Stacking Context
How are direct children actually positioned in a stacking context?
- The stacking context container gets placed first.
- Elements with negative
z-index
. - Elements with no
z-index
orz-index
that is invalid on that element. - Elements with
z-index:auto
,z-index:0
, or positioned elements with no explicitz-index
. - 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
- div1
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;)
- div2(position:relative; z-index:1;)
- div4(position:relative; z-index:2;)
- div1
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.
Top comments (0)