How Many Layers Does a Website Have?
What z-index does a modal need to always be visible above all other elements? Most frontend developers set a value somewhere between 99999 and 99999999. And perhaps we could fit under 10. Meet stacking context - a CSS mechanism worth knowing.

From this article you will learn:
- What is stacking context?
- Why does z-index: 999999; not work?
- How many ways are there to create a new stacking context?
- What is the CSS isolation property responsible for?
Try to think of any website. Got one? Great, so now I will ask you a simple question: in how many dimensions was it designed? I would not be surprised if the answer were two. What we see is flat, after all, and interface elements are arranged vertically and horizontally. But what if I told you that this is not entirely true? Websites are always designed in three dimensions, and not because designers happen to feel like it. Graphic programs arrange new elements in layers. During implementation it is similar, but this comes from CSS assumptions and from its mechanism called stacking context.
The Third Dimension
You probably remember the x, y, and z axes from primary school. Each of these axes in a coordinate system lets us define the position of a point. Defining only one value lets us place a point on one plane. To determine the position of an element in space, we need to know all 3 values. This lets us very precisely define what is happening with our point.
Imagine that the HTML elements of a website are arranged along the z axis, directed toward the user who is currently looking at that website. We can safely say that they are arranged in space like layers, according to the order of priorities assigned to them. The higher an element's priority, the closer it is to the user. These are the general assumptions, and if we stopped here, it would actually be very simple.
<div class="item-1">Item 1</div>
<div class="item-2">Item 1</div>
<div class="item-3">Item 1</div>The structure of the elements from the example above on the z axis will follow the rendering order of the elements, from top to bottom. The element with the item-1 class will be placed lowest, and item-3 will be closest to the user.
The situation becomes more complicated, however, when HTML elements have children. Then their order on our z axis is no longer that obvious, and managing it can become quite a challenge. Fortunately, CSS has a mechanism that organizes this. Stacking context (in Polish literature you can find terms such as "stos kontekstu" or "kontekst układania"), because this is what we are talking about, allows HTML elements to be arranged and grouped by setting their starting position based on a base element. Which element will that be? It depends. Sometimes it will be the direct parent, sometimes the document root, and sometimes another "initial" element in the structure.
It is worth adding here that many such contexts will appear within our page. Each of them will be completely independent from its siblings, each can be contained inside other contexts, and at the same time together they will create a hierarchical structure that is a kind of subset of the structure of the whole HTML document. What matters is understanding in which situations they appear and how to use them, or possibly overcome them. After all, we know that z-index: 99999; does not always work the way we would expect.
Misunderstood z-index
The CSS property used to manage stacking context is z-index. z-index can accept numeric values, both negative and positive. In addition, it can accept the value auto, which by default is set to 0 and, importantly, will not create a new "context stack". The auto value is the default. Therefore, adding auto to z-index, or simply omitting it, will make elements be arranged according to the structure of the HTML document. I used a few simplifications in the paragraph above, but I will clarify them below.
Setting a numeric value, on the other hand, will initialize such a new context, but does it always? It would be too simple if it did. This is where we arrive at 13 cases in which stacking context will be established.
13 Cases Worth Knowing
As we already know, simply setting z-index will not generate a new context for us. As I mentioned, elements will be placed as layers inside the nearest existing stacking context. Of course, we will search up the tree hierarchy, and if we do not find any context, we will reach the root of our document, which in most cases is the <html> element. This is our first case.
Stacking context is always created for the document root.
The next two cases concern combining z-index with the position property. By default, all HTML elements have static positioning (static). By changing the position to relative (relative) or absolute (absolute) and setting z-index as a numeric value, we separate a new context.
When setting position to fixed or sticky, we do not have to add z-index for a new stacking context to be created. It will almost always be created - the exception is the sticky property in older desktop browsers (on mobile there will be no exception).
The fourth and fifth cases are combining display: flex; or display: grid; with z-index. The sixth is setting a value lower than 1 for the opacity property. The seventh case is using one of the following properties: transform, filter, backdrop-filter, perspective, clip-path, mask, mask-image, or mask-border with a value other than none.
The first seven cases are fairly common, which makes them quite easy to remember. The next 5 rules that will create a new stacking context for us are:
- the
container-typeproperty with the valuesizeorinline-sizein a container query (@container), - the
mix-blend-modeproperty with a value other thannormal, - the
isolationproperty with the valueisolate, - the
containproperty with the valuelayoutorpaint, or with composite values containing one of them, such ascontentorstrict, - the
will-changeproperty whose value points to any property that causes new contexts to be created.
The last case is interesting. It concerns elements that are on the top layer of the document and cover the full height and width of the displayed area, that is, the viewport. Elements placed in this layer will create a new context together with their corresponding ::backdrop pseudo-elements.

Let us look at the example below to understand what happens when a new context is created.
<header>This is my header</header>
<main>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ad, quam!</p>
<div class="modal">This is my modal</div>
</main>header {
background: red;
padding: 20px;
/* Creating a stacking context */
position: relative;
z-index: 2;
}
main {
background: blue;
padding: 30px;
color: white;
position: relative;
}
.modal {
background: green;
padding: 20px;
top: -25px;
/* Creating a stacking context*/
position: absolute;
z-index: 9999;
}In principle, the element with the modal class has the highest z-index. If we look at the structure of our document, it is inside the <main> element. The <main> element does not create a new context, but because it has relative positioning, it lets us manipulate the modal's position relative to <main>. Taking the above into account, our modal has been assigned to the stacking context created on the main element, meaning on <html>. The <header> is also placed in the same context. Comparing the z-index values of both elements, we can immediately see that the modal should be above everything. And that is indeed the case.

The modal in the example above has the highest z-index. Both the header and the modal are in the same stacking context.
The situation changes dramatically when we create a new stacking context in <main> with a lower z-index than <header> has.
main {
background: blue;
padding: 30px;
color: white;
/* Creating a stacking context */
position: relative;
filter: grayscale(0.5);
}
<main> now creates a new stacking context that has lower priority than <header>. The modal inside <main> has therefore hidden under the header.
In our example, adding the filter property creates a new stacking context that has lower priority than <header> and places it below it on our z axis. Ultimately this causes our modal, despite having a much higher z-index, to appear under the header.
It is also worth adding that, according to the general assumptions of z-index, for it to work it needs a position other than static. This rule has one exception, however - it concerns child elements of flexbox. Flexbox children can use z-index even when they have static positioning.
The Power of Isolation
There are quite a few cases in which stacking context is created within a website. Most of them add different kinds of side effects, such as transformations or changes to the way elements are displayed, in addition to creating a new context.
Consciously creating contexts within a web application can be very valuable because it lets us choose the order of layers and avoid mistakes that may be costly to fix in the future. When we want to create a new stacking context and nothing more, we can use the underestimated and probably little-known isolation: isolate property. The only thing this operation will do is create a new context where one has not already appeared as a result of other actions.
Summary
CSS is a specific language. On the one hand, it is very simple and seems intuitive, but it also has many mechanisms that we do not really need to know in order to write it. Seemingly, we can create code for years and not be aware of how it really works. Only digging into the subject while dealing with "strange bugs" helps us master this area better. CSS is also difficult because it practically does not give programmers any information about errors, warnings, and so on. It is elastic. Whatever we do will work, somehow. Because of that, it can honestly discourage you.
Stacking context is one of those hidden mechanisms. Learning and mastering it will let us use the z-index property consciously, without strange tricks like z-index: 999999;.
Sources
- Dlaczego z-index nie działa?
- Stacking context
- Minimum and maximum value of z-index?
- Top layer
- Layered presentation
- What The Heck, z-index??
- Can someone explain stacking contexts?
- How to Create a New Stacking Context with the Isolation Property in CSS
- Kolejność nakładania elementów i konteksty stosu
- How z-index Works
- Understanding z-index
- z-index




Comments (0)
No one has posted anything yet, but that means.... you may be the first.