Anne van Kesteren

IE’s relative z-index calculation

As defined, z-index does not inherit nor does it depend on its ancestors. As implemented, well, that differs a bit. A typical thing is dropdown menus. While they are declared evil by the famous, some people want them. So I build.

I used a widespread technique and had this in my CSS:

ul#navigation li{
 position:relative;
}
ul#navigation ul{
 position:absolute;
 z-index:1000;
 …
}

… now in Internet Explorer. When something after that was absolutely positioned the dropdown menu would be painted behind it. I had no clue. I thought positioned boxes where among the things that were supported best by IE, but apparently I trapped on a bug in the implementation. It appears that IE checks ancestors and calculates the z-index property based on those that are positioned relative or absolute. If they don’t have any z-index property specified, descendents on which the z-index property is specified will not live in a higher level among other positioned elements.

Assume that every positioned element has a z-index value of 1 by default. In normal browsers any element that has another z-index specified which is higher than the default will be rendered on top. In IE, considering the above example, that means something like this 1 – 1000. So a base level of default and within that default positioned element it is the highest. Other browsers render the above as 1000. There should not be such a thing as 1 – x, but IE has that unfortunately. So I solved it by adding this declaration (merged of course):

ul#navigation li{
 z-index:1000;
}