163

I've isolated a little test case of IE7's z-index bug, but don't know how to fix it. I have been playing with z-index all day long.

What is wrong with z-index in IE7?

Test CSS:

input {
    border: 1px solid #000;
}

div {
    border: 1px solid #00f;
}

ul {
    border: 1px solid #f00;
    background-color: #f00;
    list-style-type: none;
    margin: 0;
    padding-left: 0;
    z-index: 1000;
}

li {
    color: #fff;
    list-style-type: none;
    padding-left: 0;
    margin-left: 0;
}

span.envelope {
    position: relative;
}

span.envelope ul {
    position: absolute;
    top: 20px;
    left: 0;
    width: 150px;
}

Test HTML:

<form>
  <label>Input #1:</label>
  <span id="envelope-1" class="envelope">
    <input name="my-input-1" id="my-input-1" />
      <ul>
        <li>item</li>
        <li>item</li>
        <li>item</li>
        <li>item</li>
      </ul>
  </span>
  <br><br>
  <label>Input #2:</label>
  <span id="envelope-2" class="envelope">
    <input name="my-input-2" id="my-input-2" />
  </span>
</form>
rezna
  • 2,243
  • 2
  • 17
  • 16
  • If you are looking for a work around and you do not rearrange all your html to nicely be in some stack context try this: http://brenelz.com/blog/squish-the-internet-explorer-z-index-bug/ – Nasaralla Aug 05 '11 at 16:08

11 Answers11

269

Z-index is not an absolute measurement. It is possible for an element with z-index: 1000 to be behind an element with z-index: 1 - as long as the respective elements belong to different stacking contexts.

When you specify z-index, you're specifying it relative to other elements in the same stacking context, and although the CSS spec's paragraph on Z-index says a new stacking context is only created for positioned content with a z-index other than auto (meaning your entire document should be a single stacking context), you did construct a positioned span: unfortunately IE7 interprets positioned content without z-index this as a new stacking context.

In short, try adding this CSS:

#envelope-1 {position:relative; z-index:1;}

or redesign the document such that your spans don't have position:relative any longer:

<html>
<head>
    <title>Z-Index IE7 Test</title>
    <style type="text/css">
        ul {
            background-color: #f00; 
            z-index: 1000;
            position: absolute;
            width: 150px;
        }
    </style>
</head>
<body>
    <div>
        <label>Input #1:</label> <input><br>
        <ul><li>item<li>item<li>item<li>item</ul>
    </div>

    <div>
        <label>Input #2:</label> <input>
    </div>
</body>
</html>

See http://www.brenelz.com/blog/2009/02/03/squish-the-internet-explorer-z-index-bug/ for a similar example of this bug. The reason giving a parent element (envelope-1 in your example) a higher z-index works is because then all children of envelope-1 (including the menu) will overlap all siblings of envelope-1 (specifically, envelope-2).

Although z-index lets you explicitly define how things overlap, even without z-index the layering order is well defined. Finally, IE6 has an additional bug that causes selectboxes and iframes to float on top of everything else.

Eamon Nerbonne
  • 47,023
  • 20
  • 101
  • 166
  • 4
    finally solved it :) - the relative position is really anoying so I somehow adopted your idea without the 'envelope' elements - it seems to solve the problem and also to work - just have to redesign a bit the code for suggest box - thx a lot – rezna Aug 17 '09 at 15:27
  • +1 works, but in my case i had to go up in parents almost to the body itself. Thanks by the way ;) – Somebody Sep 14 '10 at 16:01
  • 7
    **There are three different things that impact how elements overlap each other: stacking contexts, source order, and painting order.** The most obvious issues come up when dealing with [stacking contexts](http://css-discuss.incutio.com/wiki/Overlapping_And_ZIndex) -- knowing the other two will help you figure out the more esoteric gotchas. *Source: CSS-Discuss Wiki.* – rjb May 20 '11 at 18:59
  • This worked for me: http://stackoverflow.com/questions/814377/z-index-css-pop-up-box-and-ie7 – Paul Shapiro Jun 24 '11 at 14:32
  • 2
    I made a fiddle of this problem with comments that demonstrate the solution. http://jsfiddle.net/fNcGu/3/ – Christopher Johnson Jan 02 '13 at 18:34
  • We need some [portmanteau](http://en.wikipedia.org/wiki/Portmanteau) for `esoteric` + `educational`... like *'esocational'*. (!actualy, [looking](http://en.wikipedia.org/wiki/Education) at the [roots](http://en.wikipedia.org/wiki/Esoteric), I think that conjugates) – New Alexandria Aug 08 '13 at 22:38
  • @rjb - nice link; added. – Eamon Nerbonne Aug 09 '13 at 12:57
  • For two menus that overlap: http://www.brenelz.com/blog/squish-the-internet-explorer-z-index-bug/ – Jen Feb 18 '14 at 20:36
  • @AymericGaurat-Apelli I'd suggest for the sake of better architecture that you don't use 500 as a z-index value unless you literally have 499 other items being indexed up. Stack things in order numerically otherwise you'll end up having confusing situations where you have z-indeces of 10000 and then 999999 because you "just can't remember". I see this a lot on projects and I consider it lazy coding practice, though most people don't even give it a second thought. Organizing z-indeces will lead to more deliberate decision making when it comes to not only stacking contexts but coding in general. – dudewad Aug 14 '14 at 19:38
15

http://www.vancelucas.com/blog/fixing-ie7-z-index-issues-with-jquery/

$(function() {
var zIndexNumber = 1000;
$('div').each(function() {
    $(this).css('zIndex', zIndexNumber);
    zIndexNumber -= 10;
});
});
nixis
  • 510
  • 5
  • 10
  • after reading the "correct" solution above, I tried to formulate a solution for my considerably more complex problem than the trivial one in the question. then i threw this answer in and it worked like a charm. if the solution above is the correct one, this is certainly the easy one. thanks! – Landon May 10 '13 at 22:20
11

In IE positioned elements generate a new stacking context, starting with a z-index value of 0. Therefore z-index doesn’t work correctly.

Try give the parent element a higher z-index value (can be even higher than the child’s z-index value itself) to fix the bug.

ed1nh0
  • 1,532
  • 13
  • 17
  • 1
    Thanks. This solution worked for me by giving a z-index of the parent container, not necessarily higher than the child's z-index. – neelmeg Sep 30 '13 at 18:01
4

I encountered this issue, but on a large project where HTML changes had to be requested and became a whole issue, so I was looking for a pure css solution.

By placing position:relative; z-index:-1 on my main body content my header drop down content suddenly displayed above the body content in ie7 (it was already displaying without issue in all other browsers and in ie8+)

The problem with that was then this disabled all hover and click actions on all content in the element with the z-index:-1 so i went to the parent element of the whole page and gave it a position:relative; z-index:1

Which fixed the issue and retained the correct layering functionality.

Feels a bit hacky, but worked as required.

lukeroxout
  • 41
  • 3
3

I found that I had to place a special z-index designation on div in a ie7 specific styelsheet:

div { z-index:10; }

For the z-index of unrelated divs, such as a nav, to show above the slider. I could not simply add a z-index to the slider div itself.

  • I found that this in addition to `html {z-index:1; position:relative;}` allowed the menu to go over the carousel image on IE. – bassplayer7 Oct 11 '13 at 21:38
2

If the previously mentioned higher z-indexing in parent nodes wont suit your needs, you can create alternative solution and target it to problematic browsers either by IE conditional comments or using the (more idealistic) feature detection provided by Modernizr.

Quick (and obviously working) test for Modernizr:

Modernizr.addTest('compliantzindex', function(){
    var test  = document.createElement('div'),
        fake = false,
        root = document.body || (function () {
            fake = true;
            return document.documentElement.appendChild(document.createElement('body'));
        }());

    root.appendChild(test);
    test.style.position = 'relative';
    var ret = (test.style.zIndex !== 0);
    root.removeChild(test);

    if (fake) {
        document.documentElement.removeChild(root);
    }

    return ret;
});
spheroid
  • 992
  • 8
  • 2
1

It looks like not a ie bug, just for diffrent understanding to the css standard. If outside container is not specified the z-index, but the inner element specified a higher z-index. So the container's sibling maybe overlay the high z-index element. Even if like that, it only occurs in IE7, but IE6, IE8 and Firefox is ok.

c2j
  • 129
  • 1
  • 4
0

In IE6 in general, certain UI-elements are implemented with native controls. These controls are rendered in a completely separate phase (window?) and always appear above any other controls, regardless of z-index. Select-boxes are another such problematic control.

The only way to work-around this issue is to construct content which IE renders as a seperate "window" - i.e. you can place a selectbox over a textbox, or, more usefully, an iframe.

In short, you'll need to put "on-hover" like things such as menu's in an iframe in order to let IE place these above built-in UI controls.

This should have been fixed in IE7 (see http://blogs.msdn.com/ie/archive/2006/01/17/514076.aspx) but perhaps you're running in some kind of compatibility mode?

Eamon Nerbonne
  • 47,023
  • 20
  • 101
  • 166
  • i know about IE6 z-index bug - and this is fixed - but there's another issue with relatively/absolutely position elements/inputs in IE7 (which is fixed in IE8) - i found couple of solutions (playing with z-indeces), but none of them worked for - that's why I'm asking there... Anyway thx for the answer. – rezna Aug 17 '09 at 12:09
0

If you wanna create dropdown menu and having a problem with z-index, you can solve it by creating z-indexes of same value (z-index:999; for example).. Just put z-index in parent and child div's and that will solve problem. I solve the problem with that. If i put different z-indexes, sure, it will show my child div over my parent div, but, once i want to move my mouse from menu tab to the sub-menu div (dropdown list), it dissapear... then i put z-indexes of same value and solve the problem..

Marko
  • 1
0

This bug seems to be somewhat of a separate issue than the standard separate stacking context IE bug. I had a similar issue with multiple stacked inputs (essentially a table with an autocompleter in each row). The only solution I found was to give each cell a decreasing z-index value.

Jeremy Kauffman
  • 10,293
  • 5
  • 42
  • 52
0

I solved it by using the developer tools for IE7 (its a toolbar) and adding a negative z-index to the container of the div that will be below that the other div.

Lucas
  • 1