David Janes' Code Weblog

October 26, 2008

Tip – fixing broken menus over form on IE6 and IE7

html / javascript · David Janes · 7:17 pm ·

If you use pop up menus on your site, you may find that they don’t work very well on IE6 and sometimes on IE7 also. In particular, FORM fields (INPUT and SELECT) show above the menus and sometimes the text of BUTTONs appear on top of the menu.

This post describes how to fix this. The technique described as the same as this one here, but you may find this a little easier to implement. Honestly, your best solution is not to code menus yourself but find a menus package that handles this for you. However, you may find yourself in a situation like I where there is no choice: you have to retrofit existing code.

This is how you do it:

Add the following to your CSS – this styles an IFRAME that we’re going to drop into a menu. Initially I though the z-index was not needed, but it turns out you want to make sure the IFRAME is below the menu because otherwise the IFRAME will capture mouse and keyboard events – i.e. your menu will not work! It doesn’t seem to matter what the z-index of the IFRAME relative to the background form is though.

<style type="text/css">
.menu_iframe {
    position: absolute;
    top: 0px;
    left: 0px;
    width: 0px;
    height: 0px;
    filter: alpha(opacity = 0);
    z-index: -1;

}
<style>

Then add the following to the element that is your menu popup, at the very top:

<!--[if lte IE 7]><iframe class="menu_iframe"></iframe><![endif]-->

This will add on IE6/7 only (due to the magic Internet Explorer conditions) an IFRAME to the menu popup. Other browers will not add this IFRAME and will continue to work as per normal. Update: see the note at the bottom if you are doing this on a HTTPS secure page.

Add this code to your JavaScript:

ie_done = {}

function miframe(e_menu) {
    if (!e_menu) return;
    if (ie_done[e_menu.id]) return;
    ie_done[e_menu.id] = 1;

    var e_iframes = e_menu.getElementsByTagName("iframe");
    if (e_iframes.length == 0) return;

    e_iframes[0].style.width = e_menu.offsetWidth;
    e_iframes[0].style.height = e_menu.offsetHeight;
}

This function will – the first time it is called per-menu – resize the first IFRAME found in the menu to be the same size of the menu. Note the dependency on having an ID tag on the menu popup!

When you’re popping up your menu, call miframe with the menu element and this will make the IFRAME the same size of the menu. The IFRAME magically blocks out the form but also allows the menu to show through (play with the opacity parameter for fun: opaque is 100).

But it still doesn’t work!?

This is where it gets, well, weirder. It turns out that if you have anything marked up as position: relative, well, all the above doesn’t work. So make sure you get rid of all of those and find a different way to do fine tuning.

BUTTON tags never seem to work either – the text often filters through onto the menu. Alas, they’ve gone into the HTML junk heap for me for now until IE6 gets obsoleted. Try using a style A tag instead and suck up the ugliness.

Update: HTTPS pages

If you’re using HTTPS, the method above will have to be adjusted because you’ll start getting a “The page contains secure and non-secure items” message. My solution was to add a src="/empty.htm" tag but it occurs to me now that using src="about:blank" may work also but I haven’t tested it.

4 comments »

  1. position: relative :P

  2. admin · 2008-10-26 20:12

    It wasn’t so funny when I spent an hour ripping apart a CSS file seeing what would break the menus and what wouldn’t! ;-)

  3. admin · 2008-10-26 20:12

    I see I have formatting work to do on the comments… UPDATE: done.

  4. Scott · 2010-07-12 11:41

    I had the button problem (on top of popups) and I just set the z-index of the container div to -1. That worked everywhere except Safari for iPhone and iPad, so I made it an IE-only rule as well.

RSS feed for comments on this post. TrackBack URL

Leave a comment

Powered by WordPress

Switch to our mobile site