Revision 46798 of The stacking context

  • Revision slug: CSS/Understanding_z-index/The_stacking_context
  • Revision title: The stacking context
  • Revision id: 46798
  • Created:
  • Creator: Rod Whiteley
  • Is current revision? No
  • Comment review English

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 HTML element) anywhere in the document. In particular, an HTML element that is positioned (absolutely or relatively) and has a z-index value that is nonzero (or auto), creates its own stacking context: All its descendant elements are stacked within the parent element following the same rules previously explained. It is important to say that each stacking context is atomic and independent from the parent's stacking context. z-index values of elements contained in the child stacking context are valid only in that context. Once rendered, the whole element is atomically stacked 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 atomic: once stacking and rendering is complete, 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 HTML element) anywhere in the document. In particular, an HTML element that is positioned (absolutely or relatively) and has a z-index value that is nonzero (or auto), creates its own stacking context: All its descendant elements are stacked within the parent element following the same rules previously explained. It is important to say that each stacking context is atomic and independent from the parent's stacking context. z-index values of elements contained in the child stacking context are valid only in that context.  Once rendered, the whole element is atomically stacked 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 atomic: once stacking and rendering is complete, 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