views:

132

answers:

3

I've been trying to figure this out for over a day now, so any help would be appreciated. I have a Suckerfish menu that's made up of ul/li's. I'm trying to add some top down scroll indicators to my menu. In my example I have a blue and green indicator which are just placed inside the menu for now. These indicators are just another LI inside the UL but with a different style. I have positioned them absolutely with a fixed top. If you look at the example using firefox and hover over Blah Reports you can see the 2 indicators show up.

http://inthemind.com/test/test.html

If you open it up in IE7 and hover over Blah Reports they don't show up. But then if you hover over one of the sub items (i.e Compliance) when that sub menu expands then the indicators do become visible. I can't figure out what is changing to make the indicators show up once a sub menu expands.

If some one could give me a hint or tip as to what is missing to get this to work in IE I would really appreciate it.

Thanks, Raul

p.s) I have to use quirks mode

Update So I have narrowed it down to the fact that IE wont resolve the absolute positioned elements because the ul is hidden and IE doesn't go back and recalculate the positions when the ul becomes visible.If I wait untill the ul is visible then i re-assign the class to the indicators to reset the positioning on the elements it seems to make them show up. It's not ideal because now my indicators don't fade in with the menu, but show up after the fact.

Any other tips ?

A: 

Have a look at this it worked for me a while back. Althought not 100% sure if its what ur looking for, may be useful to somebody

Adam
It doesn't apply. In his case he has 2 stacking contexts. Where in my case I have a stacking context on my UL that all the LI's are a part of.
HaxElit
A: 

a couple things to keep in mind:

all your z-indexed elements should be position: relative or position: absolute or else IE 6 and 7 won't treat them correctly.

also, IE 6 and 7 treat z-index relative to its sibling elements, not to all elements. ex =>

<div style="z-index: 2;">
  <div id="d1" style="z-index: 1000"></div>
</div>
<div style="z-index: 1;">
  <div id="d2" style="z-index: 2000"></div>
</div>

in this example, #d1 would be appear #d2.

you can also adjust the order of sibling elements in the DOM to get the desired z order.

if you are using jQuery, here's a potential quick fix =>
http://thepalmcivet.com/post/121898767/fixing-internet-explorers-z-index-bug-with-jquery

thepalmcivet
A: 

Well I figured it out for those of you who are interested. What ends up happening in IE is that if the parent element changes from display: none to display: block the absolutely positioned child elements never get processed in the layout engine so they never get their initial offsets set.

So what you have to do is set the parent to display: block, reset the class on the indicator LI's so the layout engine kicks in, then you have to force the layout engine to lay everything out by calling offsetTop. Once the elements have been positioned we can then set the parent back to display: none.

The reason for forcing the layout engine to refresh is that IE will coalesce all style changes until the javascript has finished meaning that the offsets will never get recalculated.

Here is the code that fixed the issue:

if ($.browser.msie && $.browser.version <= 7) {
    var il = $ul.data('indicatorLayedOut');
    if (il == null) { // We only have to do the layout once
        var $ind = $ul.find('>.indicator');
        $ul.css('visibility', 'hidden').css('display', 'block');

        // Force IE to re-style the indicators. If we omit this then the layout engine
        // will not update the position and cause the indicators to not show up
        $ind.addClass("indicator");

        // We then have to iterate through
        // and pull the offset so we can
        // force a dom update
        $ind.each(function() {
            var oy = this.offsetTop, ox = this.offsetLeft;
            //console.log("X: " + ox + ", Y: " + oy);
        });
        $ul.css('display', 'none').css('visibility', 'visible');

        $ul.data('indicatorLayedOut', true);
    }
}
HaxElit