Background
When HTML elements overlap on the page, they have to be layered – one element has to be in front of, and the other behind on the z-axis (relative to the plane of your monitor, y-axis is up and down, x-axis is left and right, and the z-axis is the third dimension/depth, from front to back – the axis drawn from your nose to the monitor). The element on the bottom may be hidden by the element on top. The z-index property of an element determines how an element will be layered relative to its sibling elements. A higher z-index element will be layered above a lower z-index element.
Note that z-index only affects elements with position (e.g. position:relative;, position:absolute; – not position:static;), so we’re making that assumption when discussing z-index here.
I highly recommend reading this excellent explanation of z-index if you are struggling with the concept, as it is very important to understand.
A common misconception is that z-index values are global. They are not – you can’t just take any two random elements in an HTML structure and layer them relative to one another via z-index. z-index values are relative to their element’s siblings only; outside of that parent container, they have no effect. So if Element B is hidden under Element A, but they are NOT siblings (sharing the same parent element), you can increase the z-index of Element B to 50 billion and it will have no effect.
A silly example
One way to think of this is that you have two pieces of transparent paper, A and B, each with several colored sticky notes on them. When you put them down on the table, they overlap. Either paper A or paper B has to be on top – so ALL sticky notes on one sheet will be layered above ALL sticky notes on the other. If we have this tree structure:
- Paper A - - Red Note - - Purple Note - Paper B - - Green Note - - Blue Note - - Yellow Note
Case 1: Sibling Layering
If we want the Blue Note on top of the Yellow Note, we just set move the stickies around on Paper B – we set the z-index of the Blue Note higher than the Yellow Note, and we’re all set.
Case 2: Non-sibling Layering
If we want the Blue Note layered on top of the Red Note, we have to put Paper B on top of Paper A, because we can’t move the stickies from paper to paper. That is, we must set Paper B’s z-index higher. All the notes (child elements) of Paper A are layered together relative to all the notes (child elements) of Paper B.
Case 3: z-index limitations
If we want the Blue Note on top of the Red Note, and the Red Note on top of the Yellow Note, this is not possible. Only one can be on top because only one Paper can have the top spot.
Synopsis
In short: when we layer elements on the same paper, we just move the stickies around (change the z-index of the child elements). When we layer elements from different papers, we have to shuffle the papers themselves (change the z-index on the parent elements).
The Problem
Depending on how your theme is laid out, your header area may be layered lower than your content area. If so, your content area may block UberMenu’s submenus. We’ll need to re-position the header (which contains UberMenu) so that it is layered on top of the content area.
The Solution
The solution is to apply a bit of CSS, and the pattern is very simple:
/* This is an EXAMPLE. Selectors will be replaced by elements relevant to your theme */ #header{ position:relative; z-index:50; } #content{ position:relative; z-index:30; }
The above is an example – the exact selectors will vary depending on your theme. #header is the element that wraps UberMenu, which is a sibling of #content, the element that is obstructing the view of the submenus. The z-index values are self-explanatory – #header will be layered on top of #content because 20 > 10. The position:relative is important because z-index is not applied to statically positioned elements (the default position property value is static).
The key is to locate the appropriate elements to layer. Again, they must be sibling elements for this to work. Basically, you want to walk up the DOM tree (this is easy to do in a web inspector like Chrome Developer Tools) until you reach adjacent ancestor nodes. For example, with this HTML structure:
<div id="wrap"> <div id="nav-container"> <div class="ubermenu"> ... </div> </div> <div id="content"> <div id="overlapping-element"></div> </div> </div>
Let’s say #overlapping-element
is hiding .ubermenu
‘s submenus. We can’t apply z-index to those two elements specifically, because they do not have the same parent element, therefore they will not be layered relative to one another – their relative layering is determined by their ancestor elements.
Instead, we look for their ancestors which are siblings – #nav-container
and #content
. Another way to think of this would be to find the first common ancestor of the two target elements (#wrap
in this example), and then apply the relative z-index to the children of that ancestor.
Our proper z-index layering CSS is thus:
#nav-container{ position:relative; z-index:50; } #content{ position:relative; z-index:30; }
In this case the correct elements are the parents, but they could be several elements removed from the target elements in practice.
Internet Explorer
Internet Explorer, as usual, is naughty. Even if your layering works properly in all other browsers, z-index in Internet Explorer (usually IE7, sometimes IE8) may still need to be adjusted. Just because it’s only happening in IE doesn’t mean it’s not z-index related.