DEV Community

Cover image for What is this stacking context?
Marzia
Marzia

Posted on • Updated on

What is this stacking context?

According to the MDN Web Docs site 'The stacking context is a three-dimensional conceptualization of HTML elements along an imaginary z-axis relative to the user, who is assumed to be facing the viewport or the webpage. HTML elements occupy this space in priority order based on element attributes'.
An element can create is own stacking context in different scenarios, one of those is when setting z-index to any other value other than auto on an element that is positioned, meaning with the position property set to anything other than static.

Let’s get the following example

 <div class="div-1">div-1</div>
    <div class="div-2">div-2
        <div class="div-2-1">div-2-1</div>
        <div class="div-2-2">div-2-2</div>
        <div class="div-2-3">div-2-3</div>
    </div>
    <div class="div-3">div-3
        <div class="div-3-1">div-3-1</div>
        <div class="div-3-2">div-3-2</div>
        <div class="div-3-3">div-3-3</div>
    </div>

and the associated css

.div-1, .div-2, .div-3 {
    padding: 20px;
    border: 5px solid black;
    margin: 10px;
    position: fixed;
}

.div-1 {
    background: red;
    top: 50px;
    left: 50px;
    width: 300px;
}

.div-2 {
    background: lightblue;
    top: 100px;
    left: 100px;
    width: 270px;
    height: 200px;
}

.div-3 {
    background: rgb(69, 214, 69);
    top: 130px;
    left: 270px;
    width: 280px;
    height: 200px;
}

.div-2 div, .div-3 div {
    background: darkgray;
    color: white;
    padding: 10px;
    border: 5px solid black;
    margin: 10px;
    width: 130px;
}

.div-2-1 {
    top: 200px;
    left: 230px;
}

.div-2-2 {
    top: 230px;
    left: 260px;
}

.div-2-3 {
    top: 260px;
    left: 300px;
}

.div-3-1 {
    top: 200px;
    left: 230px;
}

.div-3-2 {
    top: 230px;
    left: 260px;
}

.div-3-3 {
    left: 300px;
    top: 260px;
}

all the div elements have some basic css applied and position fixed to all parents elements (div-1, div-2 and div-3).

The div are being displayed in the exact same order as they are present in the html and because of their fixed position it is the way they are stacked up along the z-axis.
Changing the z-index value to div-1, div-2 and div-3 is going to alter the way the divs are being displayed, for example, changing the z-index to 2 of div-2 will result in this :

Alt Text

To understand how the stacking context works we need to focus to the children div, I’m going to set a really high value to the z-index for div-3, z-index : 500; This change it won’t alter the final layout of the page at the moment as the div-3 is already the last div being displayed, but it is applied because having a parent div with an higher z-index value is going to help to understand how the stacking context work.

Alt Text

Lets focus on the children, if I add the z-index property only to those with the css as is it would not change much as the z-index only works on positioned elements, so to make the z-index property taking effect I need to set the position property.
I have set the position to fixed and adjusted the top and left for the children for the new position value.

Alt Text

and the updated css is


.div-1, .div-2, .div-3 {
    padding: 20px;
    border: 5px solid black;
    margin: 10px;
    position: fixed;
}

.div-1 {
    background: red;
    top: 50px;
    left: 50px;
    width: 300px;
}

.div-2 {
    background: lightblue;
    top: 100px;
    left: 100px;
    width: 270px;
    height: 200px;
}

.div-3 {
    background: rgb(69, 214, 69);
    top: 130px;
    left: 270px;
    width: 280px;
    height: 200px;
    z-index:500;
}

.div-2 div, .div-3 div {
    background: darkgray;
    color: white;
    padding: 10px;
    border: 5px solid black;
    margin: 10px;
    width: 130px;
    position: fixed;
}

.div-2-1 {
    top: 150px;
    left: 130px;
}


.div-2-2 {
    top: 180px;
    left: 160px;
}

.div-2-3 {
    top: 210px;
    left: 200px;
}

.div-3-1 {
    top: 200px;
    left: 330px;
}

.div-3-2 {
    top: 230px;
    left: 360px;
}

.div-3-3 {
    top: 260px;
    left: 400px;

}

Now let’s set the z-index for the one of the children of div-2, I have assigned the value 500 to the div-3, I’m going to assign a z-index:501 to div-2-2.

Alt Text

What is happening here is that the div-2-2 goes on top of the other 2 div contained in the div-2 parent but it is not being displayed on top of div-3 even though I have assigned a higher value to z-index, this is because of the stacking context.

What it means is that each element for which we have set the position property to a value other than static, has created his own stacking context so when the z-index of the children elements are set they became relative to the stacking context of the parent. If we want to have the div-2-2 displaying on top we will need to set the z-index of the parent(div-2) to be higher of all the other div(div-1 and div-3).

Top comments (0)