This last example shows problems that arise when mixing several positioned elements in a multi-level HTML hierarchy and when z-index
values are assigned using class selectors.
Let's take as an example a three-level hierarchical menu made from several positioned div
elements. Second-level and third-level div
elements appear when a user hovers or clicks 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, the z-index
property 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 (the three dots "..." represent multiple repetition of the previous line):
- 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 (
- 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.
Note: In the source code you will see that second-level and third level menus are made of several div
elements contained in an absolutely positioned container. This is useful to group and position all of them at once.