CSS stacking contexts: What they are and how they work
Stacking contexts are an aspect of CSS that trips up most developers. I don't think I fully understood them until I wrote the layout chapter of CSS Master. Sure, I understood that z-index
required position
to be something besides static
. But that's about as far as my comprehension went, even after reading Philip Walton's What No One Told You About Z-Index fiftyleven times.
That's no shade to Philip, by the way. Like I said: stacking contexts are tricky.
So what is a stacking context? A stacking context is an element that contains a set of layers. This can be a root stacking context, as created by the html
element. Or it can be a local stacking context, as created by specific properties and values.
"Contains a stack of layers" is a weird phrase, but a simple concept. Within a local stacking context, the z-index
values of its children are set relative to that element rather than to the document root. Layers outside of that context — i.e. sibling elements of a local stacking context — can't sit between layers within it.
Here's an example. Use the toggle to switch in and out of a local stacking context for A.
In this example, #a p
(Child of A
) has z-index: 1
applied, while #a
and #b
have z-index
values of auto
. Since #a p
is positioned and has a positive stack level, it sits on top of both #a
and #b
within the root stacking context.
Changing transform: none
to transform: scale(1)
for #a
, however, triggers a local stacking context. Now the z-index: 1
value for #a p
is now calculated relative to #a
instead of the document root.
Stacking contexts — whether local or root — follow a set of rules that determine the stacking and painting order of elements. Children of a stacking context are painted from bottom to top in the following order.
- Elements with a negative stack level, typically elements with
z-index: -1
- Elements with a
position
value ofstatic
. - Elements with a stack level of 0, typically positioned elements with a
z-index
value ofauto
. - Elements with positive stack levels, e.g. a positioned element with a
z-index
value of1
or higher.
Two elements with the same stack level are layered based on their source order. Successive elements stack on top of their predecessors.
A handful of CSS properties and values trigger a new stacking context. These include opacity
when its value is less than 1 (e.g.: .99
), filter
when its value is something other than none
, and mix-blend-mode
when its value is something other than normal
.
The transform
property, as you may have guessed, is a property that can trigger a stacking context — but only when its value isn't none
. This includes identity transforms1, such as scale(1)
and translate3d(0,0,0)
.
In the example above, #a
and #b
have the same stack level, but #b
is the second element in the source. When transform: scale(1)
is applied, #a p
becomes contained within the local stacking context of #a
. As a result, #b
rises to the top of the stack.
-
Identity transforms have no visual effect on the element to which they're applied, but trigger a new stacking context. ↩
Get CSS Master
Did you learn something from this blog post? You might like the latest edition of CSS Master. It contains several nuggets of CSS joy like this one. Buy now from SitePoint