IE is ignoring Z-Index on positioned elements

IE yet again is proving to be the bane of my existence. The top of a site I'm working on has a horizontal menu, an item of which triggers a pure-CSS menu that is positioned absolute within the parent menu DIV (positioned relative). This places the menu perfectly in both IE and the W3C compliant browsers.

The problem arises when I have more positioned elements further down on the page. These are also positioned relative, because there is data inside them that needs to be positioned absolute... again, this displays properly in all browsers I've tested it on.

The problem is, that then the top menu is opened, part is obscured by the positioned elements further down the page - in effect, it's positioned BELOW these elements even though there are z-index properties defined on all. (in both the CSS file and inline).

The only way to get IE to display this properly is to place the actual HTML for the menu at the bottom of the page, below (in DOM terms) the positioned elements elsewhere on the page. I would only do this as an absolute last resort.

All Elements are the same type (div). Here is the relevant HTML:

<div id='menu'>
<div id='cat_menu' style='display:none;z-index:10000;'>
<table cellspacing='0' cellpadding='0' class='brmenu' width='100%'>

<div class='product_new' style='z-index:20;'>[data]</div>
<div class='product_listing' style='background-color:#FFFFFF;'>[data]</div>

And the relevant CSS:

div#menu {
height: 26px;
padding: 0;
position: relative;

div#cat_menu {
position: absolute;
top: 25px;
left: 115px;
width: 300px;
z-index: 1000;

 div.product_new {
background-image: url("/images/sp_images.png");
background-position: 0 -108px;
background-repeat: no-repeat;
padding 0px;
height: 40px;
font-size: 9pt;
margin-top: 5px; 
position: relative;
z-index: 20;


I had the same problem. After playing around a bit I agree with David: "IE only reliably renders z-indexes for sibling elements."

I did come up with an easy alternate solution. It seems that ie renders z-index for non sibling elements as zero (as if they didn't have a z-index). I solved the problem by setting the offending elements and their parent elements to have a negative z-index, putting them below the elements with z-index reset to zero by ie.


The solution above for jQuery seems to work with Prototype as well... I've included the PrototypeJS code below:

var zIndexNumber = 1000;
$$("div").each(function(e) {
    e.setStyle({ zIndex: zIndexNumber });
    zIndexNumber -= 10;

A couple of notes:

  • suckerfish dropdowns are proven to work well. Why reinvent the wheel?
  • IE only reliably renders z-indexes for sibling elements. Due to this, it's best to only "z-index" elements that are direct children of the BODY tag.
  • If you don't want to change your markup, you will likely need to set a z-index on the #menu element above "20". The problem is that setting a z-index takes the element out of the flow (which is undesirable).
  • the style="..." attribute makes css incredibly specific (requiring you to use "!important" in your stylesheet. Please don't forget to migrate those style attributes)
  • "position: relative" triggers "hasLayout" for IE

Need Your Help

Generate the facebook signature using my applications secret key?

session facebook signature

When you build a website with "facebook connect" and you log into facebook with your username and password, facebook then sets a session on your website.