IE7 lessons learned: the z-index bug

Update 2009/09/12 09:19—The jQuery version of the dynamic z-index function has been optimized to use hover instead of mouseover/mouseout. Thanks to commenter Eric Conner for pointing out my mistake.

Update 2009/08/04 22:22—The jQuery version of the dynamic z-index function has been added.

Update 2009/07/09 10:52—The code has been updated to make use of the latest innovations in the Prototype library, and to take suggestions from commenters into account.

 

Now that we’ve officially transferred support of our big application from IE6 to IE7, I’ve been spending more and more time delving into the nitty gritty details of making that hugely complicated layout (recently made less complicated, but that’s another blog post) work in IE7.

I had thought, initially, that IE7′s superior CSS support would make my life a lot easier, and it did in some ways: my IE7-specific stylesheet is a fraction of the size of the IE6-specific one, and the ability to use attribute selectors is huge for me. But as I should have expected, I just traded one set of headaches for another. While IE7 is far superior to IE6 in terms of CSS support (and far inferior in other ways, user interface chief among them—but that’s another blog post, too), the bugs that still exist are more subtle and far more difficult to work around.

The IE z-index bug had been around since IE4 or 5, and was finally fixed in IE8. It’s still an issue in IE7, however, and chances are that you, the web developer, still have to support it. You should read Aleksandar Vacić’s in-depth characterization of the problem to really understand what’s happening, but what it boils down to is this: the CSS 2.1 spec says that a positioned element with any integer z-index value (i.e. not auto) should create its own zero-based stacking context, and use the integer value specified to decide its place in its parent stacking context. In other words, if the positioned element has a z-index of auto, its stacking context is inherited from its parent. Internet Explorer, however, creates a new stacking context for elements with any z-index value, including auto, which wreaks all kinds of havoc and generally causes mayhem in your previously neat and orderly layouts.

So what does this mean for you? Well, if you, like many people, use any variation of ALA’s Suckerfish dropdown menus on your site, you’ll notice that any positioned element, with any z-index, that is located lower down in the code than the menus will appear above the menus—no matter what z-index the menu is given—exactly the opposite of what you want to happen. If you use IE6 or below, you’ll also see form elements like the infamous IE select box appear above the menu.

Now you know what the problem is, let’s talk about how to work around it. If the problem you’re having is with form elements bleeding through, one of the solutions described here, specifically Hedger Wang’s solution (placing your menu above an iframe with a z-index of -1), should fix you right up. Unless, of course, you have subsequent positioned and z-indexed elements in your code. Then it becomes a lot harder.

And, surprise!, that’s exactly the problem I had. I had a bunch of relatively positioned UI widgets with absolutely positioned children, each with its own flyout menu of actions:

<br />
a<br />
{<br />
  color: black;<br />
  text-decoration: none;<br />
}</p>
<p>#main<br />
{<br />
  margin: 50px auto;<br />
  padding: 10px;<br />
  width: 350px;<br />
}</p>
<p>.block<br />
{<br />
  position: relative;<br />
  margin: 0px 0px 10px 0px;<br />
  width: 100%;<br />
  height: 25px;<br />
  background-color: #e0d0d0;<br />
}</p>
<p>.badge<br />
{<br />
  position: absolute;<br />
  top: 0px;<br />
  left: 0px;<br />
  width: 21px;<br />
  height: 21px;<br />
  background-color: white;<br />
  border: 2px solid #c0b0b0;<br />
  color: #c0b0b0;<br />
  line-height: 21px;<br />
  text-align: center;<br />
  font-size: 13px;<br />
  font-weight: bold;<br />
}</p>
<p>.info<br />
{<br />
  position: absolute;<br />
  top: 0px;<br />
  right: 0px;<br />
  left: 25px;<br />
  bottom: 5px;<br />
  padding: 0px 5px;<br />
  background-color: #f0e0e0;<br />
  border: 1px solid #f0d0d0;<br />
  line-height: 18px;<br />
}</p>
<p>a.menu-activator-arrow<br />
{<br />
  display: block;<br />
  position: absolute;<br />
  top: 0px;<br />
  right: 0px;<br />
  width: 20px;<br />
  height: 18px;<br />
  background-color: white;<br />
  border-left: 1px solid #e0c0c0;<br />
  line-height: 18px;<br />
  text-align: center;<br />
  color: #c0a0a0;<br />
  font-weight: bold;<br />
  text-decoration: none;<br />
}</p>
<p>a.menu-activator-arrow:hover<br />
{<br />
  background-color: #a07070;<br />
  color: white;<br />
}</p>
<p>.menu<br />
{<br />
  position: absolute;<br />
  top: 19px;<br />
  right: 0px;<br />
  z-index: 10;<br />
  background-color: #f0f0f0;<br />
  border: 1px solid #a0a0a0;<br />
}</p>
<p>.menu ul<br />
{<br />
  margin: 0px;<br />
  padding: 0px;<br />
  list-style: none;<br />
}</p>
<p>.menu a<br />
{<br />
  display: block;<br />
  padding: 2px 5px;<br />
}</p>
<p>.menu a:hover<br />
{<br />
  background-color: #808080;<br />
  color: white;<br />
}<br />

<br />
&lt;div id=&quot;main&quot;&gt;<br />
  &lt;div class=&quot;block&quot;&gt;<br />
    &lt;div class=&quot;badge&quot;&gt;Ad&lt;/div&gt;<br />
    &lt;div class=&quot;info&quot;&gt;<br />
      some info<br />
      &lt;a class=&quot;menu-activator-arrow&quot; href=&quot;javascript://&quot;&gt;v&lt;/a&gt;<br />
      &lt;div class=&quot;menu&quot; style=&quot;display: none;&quot;&gt;<br />
        &lt;ul&gt;<br />
          &lt;li&gt;&lt;a href=&quot;javascript://&quot;&gt;choice one&lt;/a&gt;&lt;/li&gt;<br />
          &lt;li&gt;&lt;a href=&quot;javascript://&quot;&gt;choice two&lt;/a&gt;&lt;/li&gt;<br />
          &lt;li&gt;&lt;a href=&quot;javascript://&quot;&gt;choice three&lt;/a&gt;&lt;/li&gt;<br />
        &lt;/ul&gt;<br />
      &lt;/div&gt; &lt;!&#8211; /menu &#8211;&gt;<br />
    &lt;/div&gt; &lt;!&#8211; /info &#8211;&gt;<br />
  &lt;/div&gt; &lt;!&#8211; /block &#8211;&gt;</p>
<p>  &lt;div class=&quot;block&quot;&gt;<br />
    &lt;div class=&quot;badge&quot;&gt;Ad&lt;/div&gt;<br />
    &lt;div class=&quot;info&quot;&gt;<br />
      some info<br />
      &lt;a class=&quot;menu-activator-arrow&quot; href=&quot;javascript://&quot;&gt;v&lt;/a&gt;<br />
      &lt;div class=&quot;menu&quot; style=&quot;display: none;&quot;&gt;<br />
        &lt;ul&gt;<br />
          &lt;li&gt;&lt;a href=&quot;javascript://&quot;&gt;choice one&lt;/a&gt;&lt;/li&gt;<br />
          &lt;li&gt;&lt;a href=&quot;javascript://&quot;&gt;choice two&lt;/a&gt;&lt;/li&gt;<br />
          &lt;li&gt;&lt;a href=&quot;javascript://&quot;&gt;choice three&lt;/a&gt;&lt;/li&gt;<br />
        &lt;/ul&gt;<br />
      &lt;/div&gt; &lt;!&#8211; /menu &#8211;&gt;<br />
    &lt;/div&gt; &lt;!&#8211; /info &#8211;&gt;<br />
  &lt;/div&gt; &lt;!&#8211; /block &#8211;&gt;</p>
<p>  &lt;div class=&quot;block&quot;&gt;<br />
    &lt;div class=&quot;badge&quot;&gt;Ad&lt;/div&gt;<br />
    &lt;div class=&quot;info&quot;&gt;<br />
      some info<br />
      &lt;a class=&quot;menu-activator-arrow&quot; href=&quot;javascript://&quot;&gt;v&lt;/a&gt;<br />
      &lt;div class=&quot;menu&quot; style=&quot;display: none;&quot;&gt;<br />
        &lt;ul&gt;<br />
          &lt;li&gt;&lt;a href=&quot;javascript://&quot;&gt;choice one&lt;/a&gt;&lt;/li&gt;<br />
          &lt;li&gt;&lt;a href=&quot;javascript://&quot;&gt;choice two&lt;/a&gt;&lt;/li&gt;<br />
          &lt;li&gt;&lt;a href=&quot;javascript://&quot;&gt;choice three&lt;/a&gt;&lt;/li&gt;<br />
        &lt;/ul&gt;<br />
      &lt;/div&gt; &lt;!&#8211; /menu &#8211;&gt;<br />
    &lt;/div&gt; &lt;!&#8211; /info &#8211;&gt;<br />
  &lt;/div&gt; &lt;!&#8211; /block &#8211;&gt;<br />
&lt;/div&gt; &lt;!&#8211; /main &#8211;&gt;<br />

<br />
// When the DOM is ready,<br />
document.observe(&quot;dom:loaded&quot;, function() {<br />
  /*<br />
  ** For each link with class &quot;menu-activator-arrow&quot; inside<br />
  ** a div with class &quot;block&quot;,<br />
  */<br />
  $$(&quot;div.block a.menu-activator-arrow&quot;).each(function(l) {<br />
    // When that link is clicked,<br />
    Event.observe(l, &quot;click&quot;, function () {<br />
      /*<br />
      ** Show or hide the div with class menu that follows it.<br />
      */<br />
      l.next(&quot;div.menu&quot;).toggle();<br />
    });<br />
  });<br />
});<br />

And it looked like this in IE7:

z-index-demo.gif

The upshot of Vacić’s article is that the relatively positioned parent of your absolutely positioned menu should be given a specific integer z-index that is higher than those of subsequent positioned elements on the page in order to ensure that your popup menu appears above all other elements. However, that requires you to know precisely how many relatively positioned elements are in the page, and to manually assign a z-index to each. But in the context of my application, these widgets were dynamically generated and I didn’t know how many I would have. So how did I deal with it? The brute force way. After all the widgets had been loaded, I searched for all divs with class block, and iterated through the list, assigning subsequently smaller z-indexes to each, thereby enabling the menu belonging to the topmost widget to appear above all subsequent widgets:

<br />
function isIE()<br />
{<br />
    if(navigator.userAgent.match(/MSIE \d\.\d+/))<br />
        return true;<br />
    return false;<br />
}</p>
<p>function zIndexWorkaround()<br />
{<br />
    if(isIE())<br />
    {<br />
        var zi = 1000;<br />
        $$(&quot;div.block&quot;).each(function(block) {<br />
            block.style.zIndex = zi&#8211;;<br />
        });<br />
    }<br />
}<br />

But that’s a bit ugly. Vacić himself suggested a more elegant solution: just dynamically increase the z-index of any positioned ancestor element when your mouse is over it:

<br />
function zIndexWorkaround()<br />
{<br />
    // If the browser is IE,<br />
    if(isIE())<br />
    {<br />
        /*<br />
        ** For each div with class menu (i.e.,<br />
        ** the thing we want to be on top),<br />
        */<br />
        $$(&quot;div.menu&quot;).each(function(menu) {<br />
            // For each of its ancestors,<br />
            menu.ancestors().each(function (a) {<br />
                var pos = a.getStyle(&quot;position&quot;);</p>
<p>                // If it&#8217;s positioned,<br />
                if(pos == &quot;relative&quot; ||<br />
                   pos == &quot;absolute&quot; ||<br />
                   pos == &quot;fixed&quot;)<br />
                {<br />
                    /*<br />
                    ** Add the &quot;on-top&quot; class name when the<br />
                    ** mouse is hovering over it,<br />
                    */<br />
                    Event.observe(a, &quot;mouseover&quot;, function() {<br />
                        a.addClassName(&quot;on-top&quot;);<br />
                    });<br />
                    // And remove it when the mouse leaves.<br />
                    Event.observe(a, &quot;mouseout&quot;, function() {<br />
                        a.removeClassName(&quot;on-top&quot;);<br />
                    });<br />
                }<br />
            });<br />
        });<br />
    }<br />
}<br />

Where on-top is defined thusly:

<br />
.on-top<br />
{<br />
  z-index: 10000;<br />
}<br />

And then you’d just call zIndexWorkaround() from inside your dom:loaded statement.

Note that the above JS code depends on the Prototype JavaScript framework. The jQuery version follows:

<br />
function zIndexWorkaround()<br />
{<br />
    // If the browser is IE,<br />
    if(isIE())<br />
    {<br />
        /*<br />
        ** For each div with class menu (i.e.,<br />
        ** the thing we want to be on top),<br />
        */<br />
        $(&quot;div.menu&quot;).parents().each(function() {<br />
            var p = $(this);<br />
            var pos = p.css(&quot;position&quot;);</p>
<p>            // If it&#8217;s positioned,<br />
            if(pos == &quot;relative&quot; ||<br />
               pos == &quot;absolute&quot; ||<br />
               pos == &quot;fixed&quot;)<br />
            {<br />
                /*<br />
                ** Add the &quot;on-top&quot; class name when the<br />
                ** mouse is hovering over it, and remove<br />
                ** it when the mouse leaves.<br />
                */<br />
                p.hover(function() {<br />
                        $(this).addClass(&quot;on-top&quot;);<br />
                    },<br />
                    function() {<br />
                        $(this).removeClass(&quot;on-top&quot;);<br />
                    });<br />
            }<br />
        });<br />
    }<br />
}<br />

For a generic solution, see Shan’s comment. The jQuery and MooTools solutions for the brute-force method are also available, pointed out by commenter Matt Wood.

Hope this is of some help.

56 responses to “IE7 lessons learned: the z-index bug”:

  • Aleksandar said:

    This is similar to a solution that I have recently implemented for the piece of dynamic block that could appear anywhere on the page and have unknown size and top-left position, thus potentially clashing with any other positioned block on the page.

    That widget is javascript-powered, with onmouseover, thus when this happens, I go from source element up the parent tree, and for each element that has position:relative or position:absolute (hm, now thinking, fixed should be added as well here) I attach a class XXshown (XX being something appropriate). thus, I can then do:

    .XXshown { z-index: 10000; }

    and this will always be on top. Like I said, similar to what you do, only with class I can add additional CSS rules that may be appropriate/needed in some cases.

  • rektide said:

    i ran into this issue yesterday and spent today hacking around it. what a ginormous pain in the rump and a huge waste of time. it took me forever to isolate all the places where new stacking contexts were created.

    it immediately made me think of Alex Russell’s how IE7 can avoid irrelevancy. its unfortunate developers will never be able to make a relevant case to the world that a browser must be abandoned, its always just going to be tough marbles to you guys. well, short of detecting the IE browser and writing nasty insults instead of rendering the page, which was a tactic taken by a) 13 year olds and b) a beloved CS professor I know. ahh dream big!

    i’m sorry for your pain.

  • Shan Sinha said:

    Gents-

    Just ran into this error and followed Aleksander’s suggestion. Here is some relatively generic javascript that can be used to make this work.

    Just call zIndexIEFix(cssSelector) where cssSelector is a selector used to identify the elements whose parent’s zIndex values need to be adjusted.

    /**
    * include this bit of css
    */
    .elementShown
    {
    z-index: 10000;
    }

    /**
    * javascript
    **/
    function getStyle(oElm, strCssRule){
    var strValue = “”;
    if(document.defaultView && document.defaultView.getComputedStyle){
    strValue = document.defaultView.getComputedStyle(oElm, “”).getPropertyValue(strCssRule);
    }
    else if(oElm.currentStyle){
    strCssRule = strCssRule.replace(/\-(\w)/g, function (strMatch, p1){
    return p1.toUpperCase();
    });
    strValue = oElm.currentStyle[strCssRule];
    }
    return strValue;
    }

    function zIndexIEFix(cssSelector) {

    if (isIE()) {
    var thumbnails = $$(cssSelector);
    for (var i = 0; i < thumbnails.length; i++) {
    thumbnails[i].observe("mouseover", zIndexIEFixMouseOver.bindAsEventListener(window));
    thumbnails[i].observe("mouseout", zIndexIEFixMouseOut.bindAsEventListener(window));
    }
    }
    }

    function zIndexIEFixMouseOver(e) {
    var src = eventTrigger(e);

    do {
    var posType = getStyle(src, "position");

    if (posType == "relative" || posType == "absolute")
    src.addClassName("elementShown");
    src = src.up();
    } while (src.up);
    }

    function zIndexIEFixMouseOut(e) {
    var src = eventTrigger(e);

    do {
    var posType = getStyle(src, "position");

    if (posType == "relative" || posType == "absolute")
    src.removeClassName("elementShown");
    src = src.up();
    } while (src.up);
    }

    cheers-
    shan

  • Richa said:

    Boy, I had no idea when I wrote this post that it would account for fully half my internet traffic since. Thanks for the great comments, everyone!

    @shan: I formatted your comment a bit to make it easier to read. Thanks for sharing your solution!

  • the emotional pumpkin » Too funny for words said:

    [...] you may have seen me mention before how, every day since I wrote this post about the IE7 z-index bug, it has accounted for anywhere between 25 and 50% of my [...]

  • nsrmbo said:

    errr… did you know Google thinks you are Malware?
    http://www.google.com/interstitial?url=http://richa.avasthi.name/blogs/tepumpkin.old/2008/01/11/ie7-lessons-learned/

  • Richa said:

    Dude, that sucks. I have requested a review and hopefully this will be cleared up soon.

  • Two weirdnesses..are they related? (IE7) | keyongtech said:

    [...] clearly to dream up the right thing to key into google. Seems this one is well known as well http://richa.avasthi.name/blogs/tepu…ssons-learned/ > As if that wasn’t weird enough, I have another part of the screen where > when you click [...]

  • Tammy Hart said:

    Thank you so much for explaining this better than other sites have. My problem was identical to yours.

  • Andi said:

    I’m still having trouble with this; I couldn’t get the solution working. I was using the Suckerfish dropdown menus as an example (http://www.htmldog.com/articles/suckerfish/example/). If you take that page and modify it to add in one extra nav item, then the last nav item will wrap to a second line and the first nav item will drop down behind the last one. From there, nothing I did fixed this problem. Right now, I would be happy to manually assign a z-index to each necessary element – I don’t need the zIndexWorkaround JS yet. If someone is able to help me, could you try to fix this issue by keeping the same HTML and changing the CSS (adding z-index or anything else), and then let me know what worked? Thanks.

  • Richa said:

    I’ll try this out today and get back to you.

  • Richa said:

    How are you trying to add a new nav section? Before li#last? Each li element has a fixed width of 10 em, so if you don’t adjust the width of the top-level li elements, the fourth element will have to wrap on to the beginning of the next line, since the parent ul has a fixed width of 32 em. If all you’re doing is adding a new nav section, all you should see in IE7 is a new nav section wrapping to the next line. What other changes are you making?

  • Andi said:

    Exactly – I added a new nav section before li#last. The fourth nav item now wraps to the beginning of the next line. And you should see that if you hover over the first menu item on the first line, it goes BEHIND that fourth menu item on the second line. I was trying to get it to go in front of it.

  • Richa said:

    Right, well you want to modify the width of each top-level li—or, equivalently, increase the width of the containing ul—to make sure they all fit in one line. It’s not really good design, IMO, to do the wrapping on two lines thing with a nav menu. That is a hint that a small redesign is in order.

    But as an educational exercise, I believe, though I haven’t tried this myself, that all you’d need to do is make sure that the first li has an explicit non-auto z-index that is higher than the (likewise explicit, non-auto) z-index of the last top-level li.

  • Andi said:

    Hey, that did work! Thank you.

  • jose said:

    Hi, i have a very huge problem with this and i can’t fix it, the problem is the next,
    I have this:
    -body
    – div
    -div colum –> relative
    -div colum –> relative
    -div colum –> relative
    -/div
    -/body

    Inside this colums i have widgets with position absolute, the problem is that the widgets can be expanded if the text of the content is longer than a height of 300px,.
    when i click on the button to expand the widget, i create a semitransparence (this is an absolute div with opacity ) the semitransparence is included in the body, so when i click on expand the semitrans cover all the colums and the widgets inside, I have checked given the colum a z-index higer of the semitrans, and works, the colum is placed over the semitrans, the problem is that i have some widgets inside the colum all of them with absolute position, and if i expand one, all the widgets in this colum are over the semitrans and i have no way to put this widgets behind the semitrans;

    so at the end i have something like this:

    body
    semitrans->absolute
    page -> relative
    colum -> relative
    widget ->absolute
    widget ->absolute
    widget ->absolute
    colum -> relative
    widget ->absolute
    colum -> relative
    widget ->absolute

    I’m crazy, and i don’t find any soluction, if someone can help me, i will be thankful for it,

    I’m from spain, so, sorry for my english :)

  • Maya said:

    Thank you! Had to code it by hand, but fixed my problem. Good explanation, too.

  • Janelle said:

    Hi,

    I encountered the same problem with a WP theme I’m using to build my site. I’ve a question pertaining to the codes provided by Shan Sinha above. May I know to which file should the codes go into?

  • Jon Glick said:

    Thanks for the quick explanation of this bug and its solution – saved me a load of time.

  • Matt Wood said:

    This fix was easy to understand. I learned a lot from your article, and also found the solution for jQuery was posted here: http://www.vancelucas.com/article/fixing-ie7-z-index-issues-with-jquery/comment-page-1/#comment-105

  • Richa said:

    @Janelle, you probably have a header.php file in your template. Within the <head></head> element, you can add a script reference, like so:

    <script type="text/javascript"></script>, within which you would paste the code.

  • Richa said:

    @ Maya, Jon and Matt: Thanks; I’m happy I could be of help!

  • Richa said:

    @jose: This is terribly late, but I haven’t had a chance to look at your example yet. I will take a look very soon, though you may have solved your problem already.

  • Darrin said:

    Thanks man – this just saved my bacon in a right hurry.

  • handy said:

    would you please help me to fix this problem with IE?

    It works fine in all other browsers….

    answer must be really simple….

    DIV.ribbon-right { z-index: 100; position: fixed; right: 10px; top: 100px; !important; ; /* ie :( */ background-repeat: no-repeat; width: 120px; height: 600px; cursor: pointer;}

  • Richa said:

    I’d need to see an HTML snippet, as well. I can’t do much with just the CSS.

  • handy said:

    I thought you can see in the source….

    but anyway, let me describe a problem:

    if I describe this type of div in CSS as “fixed” – it shows in one line down at the top and center of the page. (only in IE, by the way) – other browsers – ok.

    if I describe this type of div in CSS as “absolute”- it shows as TWO LINES as intended on the sides of the page in ALL BROWSERS.

    But I want it fixed and not rolling in IE….

    Described div is used to show Google ads.

    DIV.ribbon-right { z-index: 100; position: fixed; right: 10px; top: 100px; !important; ; /* ie :( */ background-repeat: no-repeat; width: 120px; height: 600px; cursor: pointer;}

    [AD]

  • Richa said:

    Was I supposed to somehow psychically guess that the URL you put for your site in the comment metadata was the site you were talking about? Next time, please be sure to include the URL you’re referring to in the body of your message.

    Your first problem is that you have no doctype declaration at the top of your page. Without one, your browser won’t know how to render the page properly. Secondly, your site isn’t X/HTML-compliant. Once you have those two things fixed, it’ll be easier to debug, especially in IE.

    Also, are you talking about IE 7? 6? 8?

  • Brian said:

    hello and congratulations on the smartest blog/comments I’ve seen for a long time.

    Although I think the true source of my problem is IE7′s handling of iframe transparency, the best workaround solution I can come up with involves css-based z-index switching. And so I am here.

    I have a large transparent iframe in the top right corner of my site that houses a peel back advertisement. It is the first element rendered. It is completely outside of the main “wrapper” div that contains everything else and contains a z-index of 1 to ensure it peels back over everything else on the page. It works magnificently in IE8.

    Since Firefox does not support transparency, I found css-based z-index switching a suitable workaround. I simply put a “zindexswitch” class on the “wrapper” so that hovering anywhere in the page changes the z-index to 2.

    IE supports the transparency except they overlooked one thing in IE7. Input controls, specifically textboxes for me, can’t gain hover focus from behind the transparent iframe. (Only the very edges can.) And so with my peel back up, user’s can’t access my login and search controls easily.

    I hoped my solution for Firefox could translate over to this problem, but nothing I’ve tried seems to take effect. It seems to stem from this bug that has IE7 creating new z-index stacks on the fly. Will it be impossible for any element fully underneath the iframe to gain focus under IE7′s implementation? Any input is greatly appreciated.

  • Richa said:

    Brian,

    Please post some sample code or a simplified example (or alternatively, a link to a site with the code) that I could take a look at. Sounds like your layout is relatively complicated, and it would really help me to be able to look at it.

  • Brian said:

    well…the live site is http://www.lawnandlandscape.com. the z-indexing is all in place but I had to take the peel back down until I find a solution.

    i’ll work some OT tonight and see if I can duplicate this problem in some simple snippets.

  • Brian said:

    actually that wasn’t so bad…i only cannot reproduce the ability to gain focus by clicking the very edges of the text box.

    Untitled Page

    .zindexswitch { position: relative;}
    .zindexswitch:hover { position: relative; z-index: 2; }

  • Brian said:

    Untitled Page

    .zindexswitch { position: relative;}
    .zindexswitch:hover { position: relative; z-index: 2; }

  • Brian said:

    my apologies, i don’t see how to paste source into these comments

  • Richa said:

    Just email the source to the email address at the bottom of the page, and I’ll post it for you.

  • Brian said:

    Hello Richa – you can disregard my email if you like. I have found the solution. It is actually a very basic version of the javascript solutions you propose above.

    since IE7 apparently does not support z-index changes in the CSS hover pseudo class, i force it with javascript : onmouseover=”this.style.zIndex = 2″ onmouseout=”this.style.zIndex=0″

  • Richa said:

    Brian,

    Great to hear that you got it solved, though I’m sorry I didn’t get a chance to help.

    As for the hover styling, yeah, though they claim that the :hover pseudoclass works on elements other than anchors in IE7, I learned the hard way that there are still issues with its implementation, and you’re better off forcing behavior and styling changes using JavaScript.

  • Pamela said:

    Oh. My. Goodness. I have spent hours on this with a background bleeding through a footer and spacing g0ing nuts and only in IE 7.

    Finally googled the background problem, found your post and thank you so much! I set the position on the footer to relative, the z-index to 200, well above any other relatively positioned elements on the page and… fixed. Instantly. Two lines of code. (I’m feeding IE 7 a separate stylesheet so no hacks in the main stylesheet. )
    Thank you *SO* much for posting this!

  • Richa said:

    @Pamela: Great to hear that you got your problem solved. You’re very welcome!

  • Babi said:

    Hi Richa,

    I have manually assigned a z-index to the parent elements of my “suckerfish” dropdown and now works. Thanks a lot for sharing this, it saved me a big headache.

    Cheers,
    Babi

  • Patricia said:

    Hi Richa,

    I have a question regarding my template file which looks very nice, but when I create a new file it looks just a white blank page with the text in the top left of the screen. I think that I have problems with the z-index…but I tried to apply the solutions that you mention or post here in this forum…but nothing works for me…

    If you have a chance please take a look to my file…where can I post my file…?

  • Richa said:

    Patricia,

    You can email it to the address at the bottom of the page. I’ll take a look when I get the chance.

  • Handy said:

    Richa, I wanted to say THANKS for your advice.
    Declaration of ВщсЕнзу fixed my little problem.
    I am very grateful.

  • eric said:

    Note about jquery:

    You should use

    p.hover(function() {
    $(this).addClass(“on-top”);
    }, function() {
    $(this).removeClass(“on-top”);
    });

    rather than mouseover / mouseout, otherwise the menu will flicker as you hover over it.

  • Richa said:

    @eric: Good point. I’ve fixed the jQuery source to use hover.

  • mark said:

    What a headache. Thanks for the fix.

  • Patricia said:

    Hello Richa,

    I just wanted to say thank you for the explanation about my template file…I thought that I was doing something wrong…the only thing that I have to do was to save as a html file…
    Now, I have a huge problem with my website…the links are not even shown in Firefox, but it shown in IE…I don’t know how to resolve this problem…I tried to fix it for already a week…no solution founded…:(
    If you have a chance…please check it out…if you need my files let me know…

    Thanks…thanks…thanks!

    Patricia

  • Marty said:

    This saved me lots of time. Thanks!!

    In my case I had some some elements defined with position: relative; left: 0px; top: 0px;

    I was experminting by positioning them to a different location, but ended up using a Table to position them. Leaving in the position:relative :0 :0 values was not a problem in FF but in IE my new menus were showing up under things. In my case I just went in and removed the position:relative for the elements I was not changing from the normal flow and it fixed my problem.

  • Richa said:

    @Marty: you’re welcome. In case you haven’t already, you can also remove your left: 0px; top: 0px; values, since they are meaningless without a non-static position.

  • Hamish said:

    I hate this bug with a passion.

    Great article, appreciate the run-down.

  • i said:

    ah, thanks, finally fixed this

  • Gavin said:

    Thank you for taking the time to write this up. Works a treat. You have saved me hours of pain, anguish and suffering!

  • Judah said:

    Fixed! Thanks so much for this post. Very detailed and easy to understand explanation of an annoying bug.

  • Vladimir said:

    Блог отличный, буду рекомендовать друзьям!

  • Magnus Lundgren said:

    Works like a charm. I had the same problem with richfaces calendar popup and zindex. Now I just have to work out why this is still a problem in IE8. I don’t apply the code on IE8 (and it doesn’t matter if I do or not the popup doesn’t end up on top in IE8).

  • searchengineland.com said:

    Inside this colums i have widgets with position absolute, the problem is that the widgets can be expanded if the text of the content is longer than a height of 300px,.when i click on the button to expand the widget, i create a semitransparence (this is an absolute div with opacity ) the semitransparence is included in the body, so when i click on expand the semitrans cover all the colums and the widgets inside, I have checked given the colum a z-index higer of the semitrans, and works, the colum is placed over the semitrans, the problem is that i have some widgets inside the colum all of them with absolute position, and if i expand one, all the widgets in this colum are over the semitrans and i have no way to put this widgets behind the semitrans;
    +1

Leave a reply

(required)
(required) (will not be published)