« CSS « Understanding CSS z-index
Stacking context example 3
This last example shows problems that arise when mixing several positioned elements in a multi-level HTML hierarchy and when z-indexes are assigned using class selectors.
Let's take as an example a three-level hierarchical menu made from several positioned DIVs. Second-level and third-level DIVs appear when hovering or clicking on their parents. Usually this kind of menu is script-generated either client-side or server-side, so style rules are assigned with a class selector instead of the id selector.
If the three menu levels partially overlap, then managing stacking could become a problem.
The first-level menu is only relatively positioned, so no stacking context is created.
The second-level menu is absolutely positioned inside the parent element. In order to put it above all first-level menus, a z-index is used. The problem is that for each second-level menu, a stacking context is created and each third-level menu belongs to the context of its parent.
So a third-level menu will be stacked under the following second-level menus, because all second-level menus share the same z-index value and the default stacking rules apply.
To better understand the situation, here is the stacking context hierarchy:
- root stacking context
- LEVEL #1
- LEVEL #2 (z-index: 1)
- LEVEL #3
- ...
- LEVEL #3
- LEVEL #2 (z-index: 1)
- ...
- LEVEL #2 (z-index: 1)
- LEVEL #2 (z-index: 1)
- LEVEL #1
- ...
- LEVEL #1
- LEVEL #1
This problem can be avoided by removing overlapping between different level menus, or by using individual (and different) z-index values assigned through the id selector instead of class selector, or by flattening the HTML hierarchy.
Example source code
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html> <head><style type="text/css"> div { font: 12px Arial; } span.bold { font-weight: bold; } div.lev1 { width: 250px; height: 70px; position: relative; border: 2px outset #669966; background-color: #ccffcc; padding-left: 5px; } #container1 { z-index: 1; position: absolute; top: 30px; left: 75px; } div.lev2 { opacity: 0.9; width: 200px; height: 60px; position: relative; border: 2px outset #990000; background-color: #ffdddd; padding-left: 5px; } #container2 { z-index: 1; position: absolute; top: 20px; left: 110px; } div.lev3 { z-index: 10; width: 100px; position: relative; border: 2px outset #000099; background-color: #ddddff; padding-left: 5px; } </style></head> <body> <br /> <div class="lev1"> <span class="bold">LEVEL #1</span> <div id="container1"> <div class="lev2"> <br /><span class="bold">LEVEL #2</span> <br />z-index: 1; <div id="container2"> <div class="lev3"><span class="bold">LEVEL #3</span></div> <div class="lev3"><span class="bold">LEVEL #3</span></div> <div class="lev3"><span class="bold">LEVEL #3</span></div> <div class="lev3"><span class="bold">LEVEL #3</span></div> <div class="lev3"><span class="bold">LEVEL #3</span></div> <div class="lev3"><span class="bold">LEVEL #3</span></div> <div class="lev3"><span class="bold">LEVEL #3</span></div> <div class="lev3"><span class="bold">LEVEL #3</span></div> <div class="lev3"><span class="bold">LEVEL #3</span></div> <div class="lev3"><span class="bold">LEVEL #3</span></div> <div class="lev3"><span class="bold">LEVEL #3</span></div> </div> </div> <div class="lev2"> <br /><span class="bold">LEVEL #2</span> <br />z-index: 1; </div> </div> </div> <div class="lev1"> <span class="bold">LEVEL #1</span> </div> <div class="lev1"> <span class="bold">LEVEL #1</span> </div> <div class="lev1"> <span class="bold">LEVEL #1</span> </div> </body></html>
See also
- Stacking without z-index : Default stacking rules
- Stacking and float : How floating elements are handled
- Adding z-index : Using z-index to change default stacking
- The stacking context : Notes on the stacking context
- Stacking context example 1 : 2-level HTML hierarchy, z-index on the last level
- Stacking context example 2 : 2-level HTML hierarchy, z-index on all levels
Original Document Information
- Author(s): Paolo Lombardi
- This article is the english translation of an article I wrote in italian for YappY. I grant the right to share all the content under Creative Commons: Attribution-Sharealike license
- Last Updated Date: July 9th, 2005
Note: the reason the sample image looks wrong - with the second level 2 overlapping the level 3 menus - is because level 2 has opacity, which creates a new stacking context. Basically, this whole sample page is incorrect and misleading.