Search code examples
cssinternet-explorer-7z-index

IE7 Z-Index Layering Issues


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>

Solution

  • 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.