IE 6 & IE 7 Z-Index Problem

77,941

Solution 1

Agree with validator comment - validating usually helps. But, if it doesn't heres a few pointers for z-index in IE:

1) elements who's z-index you're manipulating should be on the same level ie. you should be setting the z-index of #bottom and #body

if this is not feasible then

2) IE sometimes wont apply the z-index correctly unless the elements ou are applying it to have a position:relative. Try applying that property to #bottom and #body (or #signpost)

let me know how that works out

Darko

Solution 2

Most of the answers here are wrong; some work, but not for the reason they state. Here is some explanation.

This is how z-index should work according to the spec:

  • you can give a z-index value to any element; if you don't, it defaults to auto
  • positioned elements (that is, elements with a position attribute different from the default static) with a z-index different from auto create a new stacking context. Stacking contexts are the "units" of overlapping; one stacking context is either completely above the another (that is, every element of the first is above any element of the second) or completely below it.
  • inside the same stacking context, the stack level of the elements is compared. Elements with an explicit z-index value have that value as a stack level, other elements inherit from their parents. The element with the higher stack level is displayed on top. When two elements have the same stack level, generally the one which is later in the DOM tree is painted on top. (More complicated rules apply if they have a different position attribute.)

In other words, when two elements have z-index set, in order to decide which will show on top, you need to check if they have any positioned parents which also have z-index set. If they don't, or the parents are common, the one with the higher z-index wins. If they do, you need to compare the parents, and the z-index of the children is irrelevant.

So the z-index decides how the element is placed compared to other children of its "stacking parent" (the closest ancestor with a z-index set and a position of relative, absolute or fixed), but it doesn't matter when comparing to other elements; it is the stacking parent's z-index (or possibly the z-index of the stacking parent's stacking parent, et cetera) which counts. In a typical document where you use z-index only on a few elements like dropdown menus and popups, none of which contains the other, the stacking parent of all the elements which have a z-index is the whole document, and you can usually get away with thinking of the z-index as a global, document-level ordering.

The fundamental difference with IE6/7 is that positioned elements start new stacking contexts, whether they have z-index set or not. Since the elements which you would instinctively assign z-index values to are typically absolutely positioned and have a relatively positioned parent or close ancestor, this will mean that your z-index-ed elements won't be compared at all, instead their positioned ancestors will - and since those have no z-index set, document order will prevail.

As a workaround, you need to find out which ancestors are actually compared, and assign some z-index to them to restore the order you want (which will usually be reverse document order). Usually this is done by javascript - for a dropdown menu, you can walk through the menu containers or parent menu items, and assign them a z-index of 1000, 999, 998 and so on. Another method: when a popup or dropdown menu becomes visible, find all its relatively positioned ancestors, and give them an on-top class which has a very high z-index; when it becomes invisible again, remove the classes.

Solution 3

I just had this problem and the fix I found (thanks to Quirksmode) was to give the direct parent of the node you are trying to set a z-index of it's own z-index that is at less than the z-index of the node you are trying to set. Here is a quick example that should work in IE6

<html>
  <head>
    <style type="text/css">
      #AlwaysOnTop {
        background-color: red;
        color: white;
        width: 300px;
        position: fixed;
        top: 0;
        z-index: 2;
      }
      #Header {
        color: white;
        width: 100%;
        text-align: center;
        z-index: 1;
      }
    </style>
  </head>
  <body>
    <div id="Header">
      <div id="AlwaysOnTop">This will always be on top</div>
    </div>
    <div id="Content">Some long amount of text to produce a scroll bar</div>
  </body>
</html>

Solution 4

Welcome, I solved the problem with:

.header { 
    position: relative;
    z-index: 1001;
}
.content {
    position: relative;
    z-index: 1000;
}
Share:
77,941
mattt
Author by

mattt

i like code.

Updated on June 02, 2020

Comments

  • mattt
    mattt almost 4 years

    http://madisonlane.businesscatalyst.com

    I'm trying to get the div#sign-post to sit above the div#bottom. This works fine in all browsers except IE6 & IE7. Can anyone see what the problem is here?

    Also IE6 is displaying an additional 198px to the top of div#bottom.

  • David Hanak
    David Hanak about 15 years
    I beleive this is due to the well known bug fixed by adding "position:relative" to the stylesheet.
  • hitautodestruct
    hitautodestruct over 13 years
    This behavior is because IE6/7 start a new stacking order for every element that has the position:relative. brenelz.com/blog/squish-the-internet-explorer-z-index-bug
  • Tgr
    Tgr over 13 years
    This works because it places #Header higher than #Content (which is presumably a positioned element). The relation between the z-index of #Header and #AlwaysOnTop is irrelevant. See my answer for details.
  • Jason Sperske
    Jason Sperske over 13 years
    Thank you for solving a mystery for me! :) I have had this issue with element ordering and each time I feel like I'm resorting to black magic to make it work.
  • riwalk
    riwalk over 13 years
    Good explanation. Its surprising how many people get it wrong when they try to explain this bug.
  • Julian
    Julian over 13 years
    Thanks for your explanation. It helped me understand and correct this same bug in a project I'm working on.
  • liz
    liz over 13 years
    Thank You! i have never understood the stacking order issue before. was always a mystery to me why sometimes it worked and sometimes it didnt.
  • DEfusion
    DEfusion over 13 years
    In what circumstances will this method (adding z-index to relative parent) not work and is there another work around?
  • Tgr
    Tgr over 13 years
    @DEfusion: IE6 has another bug related to vertical positioning; some elements (for example <select> or Flash) are sort of outside the document, and there is no way to position stuff above them via z-index. That is normally solved by putting an iframe between them and the popup.
  • n8wrl
    n8wrl over 13 years
    +1 Tgr. The thing I am struggling with is class-based CSS I hope to reuse in many places. I don't know what the z-order might be that I'm living in.
  • RMorrisey
    RMorrisey over 12 years
    Thanks! For a drop-down or pop-up type of widget that should always be on top of everything, using jQuery, this is really easy to fix. Call $(myWidget).parents().addClass('on-top') when opening the widget, and $(myWidget).parents().removeClass('on-top') when closing it.
  • Ricardo Zea
    Ricardo Zea almost 12 years
    @RMorrisey Great explanation, did not know this. The jQuery snippet worked for me too. Thanks!
  • Kuldeep Daftary
    Kuldeep Daftary over 11 years
    Awesome explanation thoroughly understood! Thanks a lot.
  • woolm110
    woolm110 almost 11 years
    Amazing, thank you! Spent ages trying to debug this, (which in IE is an absolute pain) read your post and sorted it within minutes, excellent explanation as well!
  • Kat Lim Ruiz
    Kat Lim Ruiz over 10 years
    really good answer which explains exactly the issue. My case was a datetimepicker in IE7, what I did was to add the calendar object to the body instead of the control container, and fixed it. The way I explain this, is because the calendar is in the body, then all roots are siblings therefore the zindex can be managed correctly since all other controls are within form, divs, etc.