The stacking context

  • Revision slug: CSS/Understanding_z-index/The_stacking_context
  • Revision title: The stacking context
  • Revision id: 46801
  • Created:
  • Creator: Maian
  • Is current revision? No
  • Comment /* The stacking context */ "z-index: 0" still creates stacking context according to CSS2.1

Revision Content

The stacking context

In the previous example, Adding z-index, DIVs are rendered one above the other (back to front), from the one with the lowest z-index to the one with the highest z-index. In that example there is only one stacking context, which is the root HTML element of the page.

Under certain conditions, a child stacking context can be created within a DIV (or in another element) anywhere in the document. In particular, an element, which is positioned (absolutely or relatively) and has a z-index value other than "auto", creates its own stacking context: All its child elements are stacked entirely within that context, following the same rules previously explained. The z-index values of its child elements only have meaning in that context. The entire DIV and its contents are stacked as a single element in the parent stacking context.

In summary:

  • Positioning and assigning a z-index value to an HTML element creates a stacking context.
  • Stacking contexts can be contained in other stacking contexts, and together create a hierarchy of stacking contexts.
  • Each stacking context is completly independent from its siblings: only descendant elements are considered when stacking is processed.
  • Each stacking context is self-contained: after the element's contents are stacked, the whole element is considered in the stacking order of the parent stacking context.

Notes:

  • The hierarchy of stacking contexts is a subset of the hierarchy of HTML elements, because only positioned and z-indexed elements create stacking contexts. We can say that elements that do not create their own stacking contexts are assimilated by the parent stacking context.


The example

Example of stacking rules modified using z-index

In this example every positioned element creates its own stacking context, because of their positioning and z-index values. The hierarchy of stacking contexts is organized as follows:

  • Root
    • DIV #1
    • DIV #2
    • DIV #3
      • DIV #4
      • DIV #5
      • DIV #6

It is important to note that DIV #4, DIV #5 and DIV #6 are children of DIV #3, so stacking of those elements is completly resolved within DIV#3. Once stacking and rendering within DIV #3 is completed, the whole DIV #3 element is passed for stacking in the root element with respect to its sibling's DIV.

Notes:

  • DIV #4 is rendered under DIV #1 because DIV #1's z-index (5) is valid within the stacking context of the root element, while DIV #4's z-index (6) is valid within the stacking context of DIV #3. So, DIV #4 is under DIV #1, because DIV #4 belogns to DIV #3, which has a lower z-index value.
  • For the same reason DIV #2 (z-index 2) is rendered under DIV#5 (z-index 1) because DIV #5 belongs to DIV #3, which has an higher z-index value.
  • DIV #3's z-index is 4, but this value is independent from z-index of DIV #4, DIV #5 and DIV #6, because it belongs to a different stacking context.


Example source code

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head><style type="text/css">

div {
   opacity: 0.7;
   font: 12px Arial;
}

span.bold { font-weight: bold; }

#div1 { z-index: 5; }
#div2 { z-index: 2; }
#div3 { z-index: 4; }
#div4 { z-index: 6; }
#div5 { z-index: 1; }
#div6 { z-index: 3; }

#div1,#div2 {
   height: 100px;
   position: relative;
   border: 1px dashed #669966;
   background-color: #ccffcc;
   padding-left: 5px;
}

#div3 {
   opacity: 1;
   position: absolute;
   width: 300px;
   height: 350px;
   top: 40px;
   left: 120px;
   border: 1px dashed #990000;
   background-color: #ffdddd;
   text-align: left;
   padding: 0px 10px 0px 10px;
}

#div4,#div5 {
   height: 100px;
   position: relative;
   border: 1px dashed #999966;
   background-color: #ffffcc;
   text-align: left;
   padding-left: 5px;
}

#div6 {
   position: absolute;
   width: 150px;
   height: 240px;
   top: 70px;
   left: 120px;
   border: 1px dashed #000099;
   background-color: #ddddff;
   text-align: center;
}


</style></head>

<body>

<br />

<div id="div1">
<br /><span class="bold">DIV #1</span>
<br />position: relative;
<br />z-index: 5;
</div>

<br /><br /><br /><br /><br /><br /><br /><br /><br />

<div id="div2">
<br /><span class="bold">DIV #2</span>
<br />position: relative;
<br />z-index: 2;
</div>

<div id="div3">
<br /><br /><br /><br />

   <div id="div4">
   <br /><br />
   <br /><span class="bold">DIV #4</span>
   <br />position: relative;
   <br />z-index: 6;
   </div>

   <br /><span class="bold">DIV #3</span>
   <br />position: absolute;
   <br />z-index: 4;
   <br /><br />
   
   <div id="div5">
   <br /><span class="bold">DIV #5</span>
   <br />position: relative;
   <br />z-index: 1;
   </div>
   
   <div id="div6">
   <br /><br /><br /><br /><br /><br />
   <br /><span class="bold">DIV #6</span>
   <br />position: absolute;
   <br />z-index: 3;
   </div>

</div>
</body></html>


Original Document Information

Revision Source

<p>
</p>
<h4 name="The_stacking_context"> The stacking context </h4>
<p>In the previous example, <i>Adding z-index</i>, DIVs are rendered one above the other (back to front), from the one with the lowest z-index to the one with the highest z-index. In that example there is only one <i>stacking context</i>, which is the root HTML element of the page.
</p><p>Under certain conditions, a child stacking context can be created within a DIV (or in another element) anywhere in the document. In particular, an element, which is positioned (absolutely or relatively) and has a z-index value other than "auto", creates its own stacking context: All its child elements are stacked entirely within that context, following the same rules previously explained. The z-index values of its child elements only have meaning in that
context.  The entire DIV and its contents are stacked as a single element in the parent stacking context.
</p><p>In summary:
</p>
<ul><li> Positioning and assigning a z-index value to an HTML element creates a stacking context.
</li><li> Stacking contexts can be contained in other stacking contexts, and together create a hierarchy of stacking contexts.
</li><li> Each stacking context is completly independent from its siblings: only descendant elements are considered when stacking is processed.
</li><li> Each stacking context is self-contained: after the element's contents are stacked, the whole element is considered in the stacking order of the parent stacking context.
</li></ul>
<p>Notes:
</p>
<ul><li> The hierarchy of stacking contexts is a subset of the hierarchy of HTML elements, because only positioned and z-indexed elements create stacking contexts. We can say that elements that do not create their own stacking contexts are <i>assimilated</i> by the parent stacking context.
</li></ul>
<p><br>
<b>The example</b>
</p><p><img alt="Example of stacking rules modified using z-index" src="File:en/Media_Gallery/Understanding_zindex_04.png">
</p><p>In this example every positioned element creates its own stacking context, because of their positioning and z-index values. The hierarchy of stacking contexts is organized as follows:
</p>
<ul><li> Root
<ul><li> DIV #1
</li><li> DIV #2
</li><li> DIV #3
<ul><li> DIV #4
</li><li> DIV #5
</li><li> DIV #6
</li></ul>
</li></ul>
</li></ul>
<p>It is important to note that DIV #4, DIV #5 and DIV #6 are children of DIV #3, so stacking of those elements is completly resolved within DIV#3. Once stacking and rendering within DIV #3 is completed, the whole DIV #3 element is passed for stacking in the root element with respect to its sibling's DIV.
</p><p>Notes:
</p>
<ul><li> DIV #4 is rendered under DIV #1 because DIV #1's z-index (5) is valid within the stacking context of the root element, while DIV #4's z-index (6) is valid within the stacking context of DIV #3. So, DIV #4 is under DIV #1, because DIV #4 belogns to DIV #3, which has a lower z-index value.
</li><li> For the same reason DIV #2 (z-index 2) is rendered under DIV#5 (z-index 1) because DIV #5 belongs to DIV #3, which has an higher z-index value.
</li><li> DIV #3's z-index is 4, but this value is independent from z-index of DIV #4, DIV #5 and DIV #6, because it belongs to a different stacking context.
</li></ul>
<p><br>
<b>Example source code</b>
</p>
<pre>&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
&lt;html&gt;
&lt;head&gt;&lt;style type="text/css"&gt;

div {
   opacity: 0.7;
   font: 12px Arial;
}

span.bold { font-weight: bold; }

#div1 { z-index: 5; }
#div2 { z-index: 2; }
#div3 { z-index: 4; }
#div4 { z-index: 6; }
#div5 { z-index: 1; }
#div6 { z-index: 3; }

#div1,#div2 {
   height: 100px;
   position: relative;
   border: 1px dashed #669966;
   background-color: #ccffcc;
   padding-left: 5px;
}

#div3 {
   opacity: 1;
   position: absolute;
   width: 300px;
   height: 350px;
   top: 40px;
   left: 120px;
   border: 1px dashed #990000;
   background-color: #ffdddd;
   text-align: left;
   padding: 0px 10px 0px 10px;
}

#div4,#div5 {
   height: 100px;
   position: relative;
   border: 1px dashed #999966;
   background-color: #ffffcc;
   text-align: left;
   padding-left: 5px;
}

#div6 {
   position: absolute;
   width: 150px;
   height: 240px;
   top: 70px;
   left: 120px;
   border: 1px dashed #000099;
   background-color: #ddddff;
   text-align: center;
}


&lt;/style&gt;&lt;/head&gt;

&lt;body&gt;

&lt;br /&gt;

&lt;div id="div1"&gt;
&lt;br /&gt;&lt;span class="bold"&gt;DIV #1&lt;/span&gt;
&lt;br /&gt;position: relative;
&lt;br /&gt;z-index: 5;
&lt;/div&gt;

&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;

&lt;div id="div2"&gt;
&lt;br /&gt;&lt;span class="bold"&gt;DIV #2&lt;/span&gt;
&lt;br /&gt;position: relative;
&lt;br /&gt;z-index: 2;
&lt;/div&gt;

&lt;div id="div3"&gt;
&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;

   &lt;div id="div4"&gt;
   &lt;br /&gt;&lt;br /&gt;
   &lt;br /&gt;&lt;span class="bold"&gt;DIV #4&lt;/span&gt;
   &lt;br /&gt;position: relative;
   &lt;br /&gt;z-index: 6;
   &lt;/div&gt;

   &lt;br /&gt;&lt;span class="bold"&gt;DIV #3&lt;/span&gt;
   &lt;br /&gt;position: absolute;
   &lt;br /&gt;z-index: 4;
   &lt;br /&gt;&lt;br /&gt;
   
   &lt;div id="div5"&gt;
   &lt;br /&gt;&lt;span class="bold"&gt;DIV #5&lt;/span&gt;
   &lt;br /&gt;position: relative;
   &lt;br /&gt;z-index: 1;
   &lt;/div&gt;
   
   &lt;div id="div6"&gt;
   &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;
   &lt;br /&gt;&lt;span class="bold"&gt;DIV #6&lt;/span&gt;
   &lt;br /&gt;position: absolute;
   &lt;br /&gt;z-index: 3;
   &lt;/div&gt;

&lt;/div&gt;
&lt;/body&gt;&lt;/html&gt;
</pre>
<p><br>
</p>
<div class="originaldocinfo">
<h3 name="Original_Document_Information"> Original Document Information </h3>
<ul><li> Author(s): Paolo Lombardi
</li><li> This article is the english translation of an article I wrote in italian for <a class="external" href="http://www.yappy.it">YappY</a>. I grant the right to share all the content under <a class="external" href="http://creativecommons.org/licenses/by-sa/2.0/">Creative Commons: Attribution-Sharealike license</a>
</li><li> Last Updated Date: July 9th, 2005
</li></ul>
</div>
Revert to this revision