Design · Culture · Spirituality

IE z-index bug with CSS dropdown menu

Standards-aware web designers generally know of the z-index bug in all versions of Internet Explorer (though, version 8 is rumored to fix it).

In the W3C’s specs, z-index is designed to affect the stacking order of positioned elements on a web page. So, an element with a z-index of 2 should always appear above an element with a z-index of 1.

In Internet Explorer, this doesn’t work like it should. Internet Explorer resets the stack when the positioned elements are separated from each other.

Example

So let’s say we have the following HTML. Fairly standard header, navigation, etc.

  1. <div id="wrapper">
  2. <div id="header">
  3. <ul id="nav">
  4. <li><a href="#">home</a></li>
  5. <li><a href="#">item one</a>
  6. <ul>
  7. <li><a href="#">sub item one</a></li>
  8. <li><a href="#">sub item two</a></li>
  9. </ul>
  10. </li>
  11. <li><a href="#">item two</a>
  12. <ul>
  13. <li><a href="#">sub item one</a></li>
  14. <li><a href="#">sub item two</a></li>
  15. </ul>
  16. </li>
  17. </ul>
  18. </div>
  19. <div id="container">
  20. <h1>Hi. This is a positioned H1</h1>
  21. <p>This page is just some friendly content to show you just how bad IE really is.</p>
  22. </div>
  23. </div>

Then, we have the following CSS.

  1. #wrapper #header {
  2. position: relative;
  3. }
  4. #wrapper #nav {
  5. clear: both;
  6. margin: 0 5px;
  7. padding: 0 5px;
  8. width: 750px;
  9. height: 30px;
  10. list-style: none;
  11. border-top: 1px solid #335a86;
  12. border-bottom: 1px solid #335a86;
  13. text-align: center;
  14. position: relative;
  15. z-index: 2;
  16. }
  17. #wrapper #nav li {
  18. float: left;
  19. margin: 0;
  20. padding: 0 0 5px 0;
  21. border: 0;
  22. position: relative;
  23. }
  24. #wrapper #nav li a {
  25. margin: 0;
  26. padding: 7px 15px;
  27. display: block;
  28. text-decoration: none;
  29. font-size: 1.2em;
  30. }
  31. #wrapper #nav a:link, #wrapper #nav a:visited {
  32. color: #888;
  33. }
  34. #wrapper #nav a:hover, #wrapper #nav a:focus {
  35. color: #335a86;
  36. }
  37. #wrapper #nav li ul {
  38. background-color: #ccc;
  39. width: 150px;
  40. height: auto;
  41. list-style: none;
  42. margin: 0;
  43. padding: 5px 0 10px 0;
  44. border: 0;
  45. text-align: left;
  46. position: absolute;
  47. display: none;
  48. }
  49. #wrapper #nav li ul li {
  50. float: none;
  51. margin: 0;
  52. line-height: 30px;
  53. height: 30px;
  54. }
  55. #wrapper #nav li ul a {
  56. padding: 7px 10px;
  57. white-space: nowrap;
  58. display: block;
  59. }
  60. #wrapper #nav li:hover ul {
  61. display: block;
  62. }
  63. #wrapper #container {
  64. padding: 10px;
  65. position: relative;
  66. }
  67. #wrapper h1 {
  68. position: absolute;
  69. left: 10px;
  70. top: 10px;
  71. height: 60px;
  72. line-height: 60px;
  73. vertical-align: middle;
  74. font-size: 2em;
  75. background: #335a86;
  76. color: #fff;
  77. }
  78. #wrapper #container p {
  79. margin-top: 60px;
  80. }

This is very common code used to trigger a CSS dropdown menu in all modern browsers. Remember that IE6, of course, requires a small JavaScript. A good example is the Sons of Suckerfish. I do not have this JavaScript on my current example, since there are plenty of other great articles about that.

When the code below the navigation, in this case the absolutely positioned h1, is any positioned element (or a select element, Flash movie, etc.), all versions of Internet Explorer prior to version 8 will cause the dropdown menus to fall behind the content.

The Fix

The fix for this is very simple, but there are incredibly large websites that use jumbled masses of iframes, extra divs, and other horrors to get Internet Explorer to display the dropdowns above the offending elements.

For a fix, we use the following CSS for the header div. See the screenshot for an example of this (again, in IE7). Click it to see a larger version.

  1. #wrapper #header {
  2. position: relative;
  3. z-index: 2;
  4. }

Now, you will also need to make sure that your container div, whatever it is called, is styled correctly. In my example:

  1. #wrapper #container {
  2. position: relative;
  3. }

This ensures that the header and the container, whatever you call them, understand their relationship to each other for the z-index fix to work.

This fix causes the dropdowns to appear above everything that is inside the content areas of the page. It works in IE7 and IE6. My example adds some code to show the <select> statement, which is another common offender.

50 Comments

  1. Chad

    Thank you! Elegant & perfect & simple solution! You saved me a great deal of grief, too!

  2. kuse

    damn.. its not work on ie 6 ..
    frame solution always better !

  3. Jonathan

    @kuse: Do you have an example of the solution not working in IE6? I’m always interested to see if these kind of challenges can be resolved in a standards-friendly way.

  4. Larry

    Thank you thank you thank you.

    Works for me in ie 7.

  5. Jonathan

    @Larry: Glad it worked for you. Feel free to come back, if you run into any issues or have any questions with it.

  6. Matt

    Larry you are a livesaver! This fix I have been looking for, for some time. Thank you so much.

  7. Jonathan

    @Matt: I’m Jonathan, but you’re welcome :) . Glad it helped.

  8. Brad Weaver

    This is the CORRECT solution. Lots of forums on the net have you adding z-index to all different parts of the drop down. You only need to add it to the header. This works on Suckerfish and Son of Suckerfish as well.

  9. Srinivas

    Thank you so much. You helped me a lot.

  10. Bill

    Sorry it doesn’t work in my IE 6 (6.0.2800.1106 with SP1). The items don’t even drop down.

    IE 7+ works great, but I need for IE6, any suggestions? Thanks.

  11. Jonathan

    @Bill: Right. To get dropdowns to work in IE6, you do need a small JavaScript. This is because IE6 does not support pseudo classes on lists, like new browsers do.

    To fix this, there are a variety of scripts available. One of the easiest to use is the Suckerfish dropdown technique from several years ago. There are others, but this one is a great start.

    The dropdowns themselves are not what I was looking to show with this particular post, though of course it is a related issue. Thanks for asking.

  12. Todd

    Thanks so much for this. Im working on a new project and knew that z-index was the problem. I tried adjusting various elements of the navbar CSS, based on many blog posts, without success. It did not occur to me to raise the z-index on the entire header wrapper (which the navbar is inside). I had given up, and instead had simply put a message in the fine print, suggesting that IE users upgrade to IE8 in order to properly view the site. Now the whole header sits in front of the content, including the navbar dropdowns. It finally works in IE7, which is what I was testing with! Handy to know it wont work in IE6 too! (Not that I care about that).

    Im leaving that message in the fine print though! :)

  13. awesome

    Thank you!
    I couldn’t figure out the reason for the life of me why the drop down menu was displaying behind only SOME of the content. This was a very concise and helpful explanation.

    Thank you again!

  14. Vicki

    Thank you for such a simple and elegant solution. I finally found your website way past midnight and was ready to tear my hair out. It worked beautifully.

    -V

  15. tom (dB)

    So simple, and works so beautifully.

  16. Ronek

    I tried pasting the code in my css sheet, but the drop sown menu is still behind the text and images in IE8. Any suggestions as to what I am doing wrong?

  17. tempest

    you save my day buddy, fantastic just simply awesome. end of the IE sucks a lot :) LOL

  18. Jonathan

    @Ronek: This is IE8 where the issue is happening? Does it also happen in IE6/IE7? What about Firefox? Also, does your HTML and CSS validate?

    Look into these things first, and see if you notice anything that tips you in the right direction. If you don’t, feel free to post a link where we can see the offending page.

  19. [...] dropdown menu Filed under: Code, Firefox, Internet Explorer — papercliphand @ 4:09 pm IE z-index bug with CSS dropdown menu | jonathan stegall: creative tension Leave a [...]

  20. Jonathan Strange
    • Jonathan Strange
    • August 5th, 2009 at 11:00 am

    Fuggin’ sweet, thanks so much. Couldn’t figure this one out.

  21. Jimmy

    Thanks for this. Worked perfectly! Had been trying to get it to work by applying the z-index to the ul ul before I found this.

  22. beckie

    YOU ROCK! Thank you!!!

  23. Nicole

    You save my life! Love you!!!

  24. Kenny

    Thank you sooo much! Great solution.

  25. Joshua

    Thanks for the fix Jonathan. It is the best explanation of it that I have seen, but it is not working on my site in ie7.

  26. Jonathan

    @Joshua: Can you send a link? I’d be happy to look at it. Also, have you checked to make sure the HTML and CSS validate? Does it work in IE6?

  27. Alexandra

    Thanks! Worked like a charm!

  28. shirley

    Thank you!
    :-( But it’s not working in IE 6.
    Please give some solution.

  29. Jonathan

    @shirley: Well, the solution depends on what you are seeing in IE6. To get dropdowns to work in IE6, which is the only difference in this case with IE7, you do need a small JavaScript. This is because IE6 does not support pseudo classes on lists, like new browsers do.

    To fix this, there are a variety of scripts available. One of the easiest to use is the Suckerfish dropdown technique from several years ago. There are others, but this one is a great start.

    The dropdowns themselves are not what I was looking to show with this particular post, though I’m happy to link to those kind of solutions.

  30. Raven Matt

    Thanks. This may have saved me. Still testing, but it seemed to work.

  31. Phillip

    Hi Jonathan,

    Great article!

    On my site it works great in IE8 but in IE7 my drop down menu appears behind a table that loads a javascript rss reader…it is bugging me a bit..

    If you ping via mail I can give you the details. I have tried the z-index but something is still off.

    Best regards,
    Phillip

  32. roy

    Shot – works well, IE is so #$@!$#@%@$%

  33. danna

    Wow, your fix did indeed fix my very thorny IE7 / z-index / drop down menu issue on this URL – http://weygandtwines.com/wine-french.htm. The theory makes perfect sense (in a warped IE7 sort of way), and to me better code is better fix than javascript.

    A thousand thank yous for saving my skin.

  34. Richard

    Excellent, this was driving me nuts, had the same problem with a dropdown falling behind a slider.

    Thanks

  35. aaroncavano

    Awesome, saved me a ton of time today, now I can get on with my work. Thanks!!!

  36. biznuge

    hmmmmm.

    This fix appears to work in showing the menu above content, but unfortunately mouse events on the contents of the menu (ul>li>ul>li>a) don’t appear to bubbling. It’s as if the display is showing the header at the correct level, but the event model in the browser is still not able to figure this out…

    got an annoying issue here that will not seem to resolve itself.

    strange…

  37. ben

    Thanks, exactly what I needed

  38. aaigg

    Thanks, I am looking it during last 6 month. It’s really help to me. Today, i solved my problem.

    Thanks again….. God bless you

  39. j.m.

    doesn’t work in IE 6 for me either. in fact, when i hover over the menu nothing happens.

  40. Jonathan

    @j.m.: If nothing happens in IE6, you do need a small JavaScript as I mentioned earlier. This is because IE6 does not support pseudo classes on lists, like new browsers do.

    To fix this, there are a variety of scripts available. One of the easiest to use is the Suckerfish dropdown technique from several years ago. There are others, but this one is a great start.

  41. Vance Bell

    A nice, clear description of the issue yields a timely 3AM bug fix for me. Thanks!

  42. Rick

    Thanks – helped me greatly!

  43. Daniel

    Thank you!. It works perfectly as you described for IE6 and IE7.

  44. Paul

    thanks very much, this was exactly what i needed to cater for the users languishing in an ie7 hell…

  45. Joe Bloggs

    Awesome. I had been struggling with fixing the z-index bug even with help from some other respectable websites, but the clarity with which you have explained and the simple example have helped me understand almost instantly the solution. how do i thank you?
    Cheers.
    you are a good man.

  46. Bob

    I copied and pasted your code, and I have the csshover.htc file to take care of IE’s :hover failings. However, your solution did not work *completely*. The H1 tag appears behind the dropdown like it should. However, when I replaced your H1 tag with a SELECT tag, the SELECT tag forces its way in front of the dropdown. Are you adding anything special to your SELECT tag in the example?

  47. Jonathan

    @Bob: Well, I’m not sure. First of all, though, see if it works in IE7 without the csshover.htc file. Of course it won’t work in IE6, but IE7 does not have the hover issue so you can test there and see if that is the problem. I’ve sometimes had weird issues with htc files, so it is possible.

    If that does fix it, you can use a conditional comment to serve a JavaScript to IE6 instead of the htc file. I’ve successfully used the Suckerfish technique, for example.

    If the htc file proves not to be the issue, though, feel free to post a link.

  48. ktsixit

    Thanks a lot :) This is the easiest and most easy to understand example-solution I’ve found about this issue.

  49. David Moore

    Lovely fix, thanks very much.

  50. Luke Raymond

    Johnathan,

    Thanks so much for this post! I have a corporate site launch on Thursday and this bug was causing me great frustration.

Post a Comment

Please provide your name, email (will not be published), and a message.

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

About the Designer

Jonathan Stegall is a web designer and emergent / emerging follower of Jesus currently living in Atlanta, seeking to abide in the creative tension between theology, spirituality, design, and justice.

Elsewhere