How I Learned about Stacking Context from Second Try

(so you don’t have to)

Developers operate with an endless stream of information every day. The speed of analyzing and digesting the raw data is crucial to your professional growth. These days, we don’t have much free time for self-education, so we all need to learn on the go. To put it simply: the faster we perceive and digest new information, the better professional we become. Yet, by learning faster, we tend to drop out and overlook tiny but very significant bits of information.

Written by Oleg Koval

Remember the last time you’ve brushed through a new piece of theory in an interesting article but never managed to use it in practice? That’s a sad reality many of us face: we spare time to read a piece of new information, close the tab/window/book, and with a blink of an eye, all the knowledge is gone.

I’ve had such an experience quite recently while working with one of the CSS features called z-index. Here’s how it went: I opened a list of tasks for the week and headed to fix a minor bug with overlapping items. I learned the topic some time ago and was absolutely sure that I knew it top-to-bottom.

“No biggie.” — I thought. It’s not a secret that you can fix such bugs by simply increasing the z-index value.

How wrong was I.

I was armed with z-index’s silver bullets: 1000, 1100, 2000, 999999 (recognize the numbers?). But none of them saved me.
A mixture of curiosity and slight desperation made me Google for theory on z-index. Here’s what I’ve found:
“The z-index CSS property sets the z-order of a positioned element and its descendants or flex items. Overlapping elements with a larger z-index cover those with a smaller one.”

I was doing everything right, didn’t I? The elements with a higher z-index should have been positioned in front of elements with a lower z-index. But what about that tiny prefix “z-”? What does it stand for?

A web page has a 3D structure: X-axis is responsible for horizontal position, Y for vertical, and Z for posing elements closer or further from an observer’s point of view.

Hence, z-order defines the element’s position on the z-axis. And the very concept of orderly placing elements relative to the z-axis is called stacking context.

If you add z-index to the positioned element, it becomes the root element of a new stacking context. Consequently, this stacking context exists only within the boundaries of an element that created it.

As the result, stacking context can have two types of descendants — simple elements and the elements that create their own stacking context. This tendency creates a hierarchical structure in which every stacking context is atomic in its nature.

In this context, the word “atomic” means that if we switch two stacking contexts, their descendants will move on the Z-axis with them.

You can also change the element’s position within the stacking context to which the element belongs.

However, you can’t change the position of an element in relation to a different stacking element.

Now that we know a little bit more about stacking context, let’s explore its elements. I’m adding a couple of common examples below (full list available here).

Ready? Here we go. These are the elements that create a stacking context:

  • Element with a position value fixed.
  • Element with an opacity value less than 1.
  • Element with a position value absolute or relative and z-index value other than auto.
  • Element with any of the following properties with a value other than none: transform, filter, clip-path.

Within each stacking context, the elements are organized according to the “back-to-front” order also known as the default stacking order.

  • Borders and background of the element forming the stacking context.
  • Non-positioned floats.
  • In-flow, non-inline-level, non-positioned descendants.
  • Inline-level, in-flow, non-positioned descendants, including inline blocks and tables.
  • Child stacking contexts with negative stack levels where the most negative ones come first.
  • Child stacking contexts with stack level 0 and the positioned descendants with stack level 0.
  • Child stacking contexts with positive stack levels where the least positive ones go first.

So now you can tell that the stacking context is ruled by very simple principles. Things get complicated when you begin to work with a hierarchy of HTML elements. Sometimes it’s just not that easy to understand or predict their behavior.

Even though I couldn’t use the magic trick of increasing the value of
the z-index, it didn’t take much time to fix the issue. All I needed to know was that two stacking contexts with the same z-index values are positioned according to default stacking order.

If I could compress this article into one line, it would say “do your homework.”

Useful reading:

Thanks for reading. We hope our article helped you to expand your expertise a bit. Stay tuned and follow us!

Engineering Your Breakthrough