How to put a DIV over a SELECT in IE6?

Everybody who tried to implement an HTML menu knows it: in Internet Explorer 6, there are some elements like SELECT that always appear in front of all other elements no matter what z-index you apply to them. Other elements that present the same problem are ActiveX controls (including Flash movies), OBJECT tags, plug-ins and iFrames. That's because these elements are implemented as windows whereas other elements are just drawn on the existing background window.

<rant>This sucks. Really. It's a typical case where an implementation detail forces web developers to go through hoops. This problem is IE only and everything works fine in all other modern browsers.</rant>

Now, is it possible to work around it? There is always the possibility of a getElementByTagName and of hiding all such elements from the page when showing an overlaid DIV. Uck. That would really puzzle your users even though it doesn't really impair usability very much in the case of a menu which will go away as soon as you take the mouse cursor out.

There is actually a much better workaround, and that's what the new ASP.NET menu is using. I suspect that most other professional menu controls do the same. Let me warn you that it's very hacky and takes advantage of a behaviour that seems as buggy as what we're trying to fix, but it's also very efficient and seamless.

The idea is to put an iFrame (which is also a windowed control) on the page at exactly the same location as your DIV. The iFrame must be added at the end of the page so that it appears in front of all other windowed controls (the windowed controls are stacked in the order in which they appear on the page). That takes care of covering any SELECT that may be in our way. Now, you may wonder what good that will achieve as I'll just cover my DIV with an iFrame instead of with a SELECT: that shouldn't buy me anything. Well, for some strange reason, it does. IE seems to be utterly confused by our little trick and just shows the DIV in front of the iframe if and only if you position the DIV after you've positioned the iFrame. It seems to forget about the windowed nature of the iFrame for what it renders after it.

If you do it using javascript, just set the position of your DIV after you've set-up the iFrame. If you do it in the HTML markup, just define the DIV after the iFrame. Here's HTML markup that successfully displays a DIV in front of a SELECT element:

<select>
 
<option>This usually appears on top in IE</option>
</select>
<iframe src="javascript:'&lt;html&gt;&lt;/html&gt;';" scrolling="no" frameborder="0"
 
style="position:absolute;width:50px;height:120px;top:0px;left:0px;border:none;display:block;z-index:0"></iframe>
<div style="position:absolute;width:50px;height:120px;top:0px;left:0px;border:solid 1px black;z-index:0">
 
This appears in front of the select in IE
</div
>

<select>
 
<option>This usually appears on top in IE</option>
</select>
<iframe src="javascript:'&lt;html&gt;&lt;/html&gt;';" scrolling="no" frameborder="0"
 
style="position:absolute;width:50px;height:120px;top:0px;left:0px;border:none;display:block;z-index:0"></iframe>
<div style="position:absolute;width:50px;height:120px;top:0px;left:0px;border:solid 1px black;z-index:0">
 
This appears in front of the select in IE
</div
>

One thing is worth noting: if you work with a secure site (with an https: protocol), you can't use "about:blank" as the url of the iFrame, otherwise you'll get a warning from IE saying that the page uses both secure and insecure contents. Not very nice to your users. So in this case, you'll just need to point the iFrame to some blank but secure page on your site. That's an extra hit to the server but hey, you already have a hit for each image on your site and that doesn't prevent anyone from having dozens of images on each page. Only in this case, it won't get cached client-side. See update below for a workaround...

Update: using "javascript:;" as the src of the iFrame in the https: case does the trick without the additional hit to the server. Thanks, Scott.

Update to the update: "javscript:;" is fine if your div is not transparent, but it will display an error message on the iFrame, so it should be avoided for transparent divs. By the way, if your div is transparent, you need to make the iFrame itself completely transparent (using an Alpha filter). That won't affect the hiding power of the iFrame (selects will actually not show through the div).

Update to the update to the update: thanks to David Anson and Kirti Deshpande who pointed me to this neat trick: using "j avascript:'<html></html>';" works well in all cases, even transparency, and avoids the https alert.

LAST UPDATE to this post: Folks, it might be a good time to stop and consider how much it costs you to support IE6. This hack to hide selects is only necessary for older versions of IE that are shrinking fast (6 or smaller; 7 and 8 are NOT affected). I actually think that it is now hurting more than helping to make your site look better in IE6. Give them a reason to upgrade, and show them how. That may be a better use of your time... Just an opinion, but please consider it.

91 Comments

  • You can also clip the select box.

  • foobar: yes, you can if you have only one DIV to overlay. In the case of a cascading menu, you would have to clip to something that's not rectangular, which is impossible. And it would be so much more complicated than this anyway...

  • Interesting. I was pretty sure that the Beta 1 hid all selects on the page when the menu was shown. It looked really funky; this hack is at least much better from a user point of view.

  • Jon: you're right. Beta 1 used to hide all select elements. The iFrame hack is available in beta 2 and later builds.

  • We use &quot;javascript:;&quot; as the src to avoid the secure/non-secure warning. Works better than putting a blank page in the site IMO. :)

  • Interesting. I'll update the post. Thanks for the tip.

  • Ron, that's very nice of you, but there's already a link to this article in the post, if you look carefully. Thanks for making it more obvious, though.

  • Thanks for the &quot;hack&quot;. I will need to try that out. I have gotten into the habbit of solving this problem by avoiding it but if I can avoid making sacrifices then that's great.



    I wonder if this would also work for other objects. I have a large flash movie that pops up on a site I am working on. The flash is set to be transparent and all the standard stuff to let it stay above the other page elements. But I noticed the DIV problem exists with my flash movie as well. I have a hunch that this same hack will make the div my flash movie is in also appear over the SELECTS.



    Do you know if this hack is browser version specific? I wonder if IE7 has corrected this problem.

  • Bertrand, am I missing something? The IFRAME has a white background.. so how is this solution supposed to work? Possibly something else in my app is breaking the hack?

  • OK, well, I guess I know what you meant about transparent being a problem.



    Results are in:



    Testing in IE6, It does show up over the SELECT as suspected. So flash is no problem. But, I guess there is no way to make that IFRAME transparent so this hack works great only if your menu has a background to cover up the IFRAME.



    Lets hope IE7 get this fixed.



    Good to know about this method anyways. Thanks BLR!

  • Collin, yes, I think you've got it figured out: the point of the hack is that the iFrame is not transparent... So for a transparent movie, I don't think this can help. But it definitely helps for a menu DIV.

  • Hi Bertrand,



    Just as a note - I don't think *anything* is cached when accessed through https (for obvious reasons).



    Josh

  • Thx for this hack...

  • For simple menus (with no submenus) you can also use the window.createPopup() method, and that goes over windowed elements.

  • Collin: thanks for the script. I can see just a little problem: if some of your selects are already hidden for whatever reason, you're going to make them visible. This can be fixed by remembering the initial state in an expando.

  • Yeah, I thought about that. For my purposes this was all that I needed since I am writing a small flash movie to the screen. Where toggling would become an issue is with menus that have multiple depths.



    Post Correction: &quot;I was tempted to make this script write a div to the page, position it where the IFRAME is and then style it to look like a drop down list but decided that was just not worth the hastle. &quot; ... I meant to say SELECT not IFRAME.

  • I noticed a little bug on my implementation....



    after resizing the window, my menu is dropped behind the selectboxes, until the page is reloaded, then it works again

  • Has anyone here faced a problem when using the client callback functionailty of ASP.NET 2.0 while having an iframe in the contentpage?

    I have used an iframe in my contentpage since I use to display a calendar. However, upon doing so, the client callback no longer works. Upon trying to dig into this, I realized that the postData variable in WebForm_DoCallback is initialized to a different value. Any help on this will be highly appreciated.

  • Rohit: if you choose to use an iFrame, what's inside the iFrame is basically another page so I wouldn't even use callbacks in this situation, I would just point the frame to a page that contains only the calendar and does regular postbacks.
    Even better, don't use an iFrame...

  • Collin Yeadon,

    As far as your code sample, do you just put it on a page? It didn't really work when that was tried. any suggestions?

  • The problem is not present in IE7. However, I very much appreciate the solutiion presented above. IE6 will be around for some time yet.

  • Thanks a lot for the hack!! I was not at all happy with hiding my selects.....

    Now I am just wondering if there is any reason not to put the content of my div into the iframe instead?:)

  • Stine: yes, there is a very good reason not to do that. If the select is in the iFrame, it will be in a different page, and thus in a different form, so you won't see it when you post.

  • "javascript:;" as the src still causes the warning message to show on https pages for me in ie6sp2...

    I have found that src="javascript:false;" works perfectly (though in firefox the iframe will display 'false', so make sure to set a background for the div above it).

    The reasoning behind this still eludes me - meh.

  • Works with https, no message.

  • Sorry that should have been
    javascript:false;

    NOT
    javascript:return false;

  • It works fine with IE7

  • Using "#" as the src of the iFrame works fine with transparent iFrame too but I'm not sure is it good for the https: case. Would someone try it, please?

  • #, if clicked - will refresh the root page, not a good idea nowadays with ajax, cms sites and the like. In other words # doesnt work fine with me :)

  • scathe: actually, # does *not* navigate away from the page if clicked, but it adds to the browser history. You can use javascript:void(0) instead anyway.

  • I have draggable div elements on my page which float over select and input elements. In IE this is very broken, as you described, so instead I've forced these draggable div elements to load in a relatively positioned span (using a bit of Collin Yeadon's code to detect the browser).

    I didn't use iframes because i had difficulties making these position properly with the draggable element.

    I've opted to leave the IE version of the site partially crippled (but still functional) until people either chuck IE into the toilet or upgrade to IE7.

  • Heh, I just spent an hour or so writing a very pretty div-powered fading tool-tips for some forms I was writing when I came accross this problem. Cheers for the solution - hopefully one day we won't have to hack things together like this.

  • With HTTPS, I've found that on IE6 it seems that error pages generated by the browser are treated as insecure, so anything that causes an error in the src of the iframe will cause the secure/insecure mix alert.

    The only thing I've found that works for me is to put a src that points to a valid html page on the server. any of the javascript options, or pointing to a page that does not exist, causes the secure/insecure alert.

  • Keith: even "j avascript:''"? (remove the space, I added it so the blog engine doesn't remove it)

  • Kevin R Hurst: You've probably solved your problem between June '06 and May '07 but since I stumbled upon this page just now...

    The script is very simple, the only way it wouldn't work is if you give it the wrong coordinates. If you use javascript to grab the values from a menu for instance make sure that you are getting the absolute top and left and not just the coordinates within whatever parent container it's in. It really does nothing but toggle so you can have it in the hide and show script of the menu and it would work fine.. Again, that is just an ugly solution as a last resort and of course it can be improved upon in many ways but why bother? IE6 will be gone within the next couple years..

  • I left a comment here a few weeks ago, but it hasn't been activated yet, so I'll submit it again:

    I've a div with a semitransparent background, which has the width and the height of the browser window, so it's shown all over the website.

    Well, there are also a few select boxes. Without the iframe they show through the div, of course. Now I've put a transparent iframe with the properties you recommended in your posting (alpha filter etc.) over the whole site.

    However, the select boxes don't show through the div any more - that's pretty good. But they aren't visible any more, more precisely: I can't see them among the semitransparent div.

    Hope you've got any advice,
    thanks

  • hnr: I'm afraid this is the best you'll get. On the bright side, IE7 is here now and it's just a matter of time that this bug becomes just one of the great memories we'll keep from IE6...

  • hello Mr. Bertrand Le Roy
    I had faced the problem, in which the menu-bar-list(writen in java script) items, were displayed behind the dropdownlist(asp.net).
    I had used iframe as an list element which solved my UI problem.
    thaks, your idea is realy amazing

  • I tried with iframe and div. But both dynamjcally by putting innerHtml. But in my case div object is hidden by iframe even if I set z-index of div more than iframe. I use IE 6. Is there any other solution?

  • TimmEH: it's the iFrame that must be absolutely positioned to be at the same place as the div, but there's no constraint on the positioning of the div itself.
    Amit: creating the elements dynamically doesn't make a difference. That's what we're doing in several of our controls. There must be something else that's different from the code presented here.

  • Dinesh: doesn't removeChild work?

  • I suspect the reason this works goes back to windows forms. When a transparent control overlaps another control, the bottom control never gets the instruction to draw the portion underneith the transparent control so all you end up seeing is the background. The HTML is rendered to the background layer as far as winforms is concerned, so by putting a transparent IFrame control over the select or Flash control the draw instruction is prevented from being issued causing the div element underneith to appear.

  • Nicholas: no, IE doesn't use any of .NET or Windows Forms.

  • Kalyan: Err, not to be rude, but the only thing I can suggest is that you read the post...

  • select box is display over the div. How to overcom that

  • Bosker: please read the post before posting a comment. Not to be rude but that's exactly what it is about.

  • i used "BLOCKED SCRIPT'&lt;html&gt;&lt;/html&gt" to fix my div overlapping with iframe in https. when i checked with my local machine iis it works perfectly wihout giving any 'non secure items' alert. but when i save file into my test server alert will popup. so i like to know if any configuration change needs to fix this issue or any other thing??
    please some body have an idea would be really appreciated.

  • Hiran: your message doesn't make it clear if you included both quotes around the html tags (I don't see the second one). The idea here is to use the javascript protocol and return a literal string that contains emtpy html.

  • Thanks very much for your article. It was really helpful to fix the problem. Keep up the good work :)

  • I'm also looking for a solution to the problem posted above by Abhishek. I have a Div that appears on top of some selects. They are all hidden fine by the iframe (which I have inside the div) but as soon as you scroll the page the selects show through, and stay there. Unfortunately I have to support IE5.5 and 6. Any ideas?? (other than the ugly method of hiding each one of the selects)

  • I tried using the onresize event ..it failed to work with me. so instead i captured the onscroll event. works perfect now. let me know if anyone foresees the code failing.
    angie

  • Rob: so you're the guy still using applets ;) Seriously, I think Java applets are just running in an ActiveX control so I'm just as confused as you are.

  • I use a charting software applet in my web applications for advanced web chart features. This is a 3rd party tool that is very effective. Is there something that you have against using applets? Regardless, if my understanding is correct, my navigation menus using this blog's principle should appear over the applet, but they do not. Any ideas?

  • Rob: I was just kidding. Sorry, I have no clue why Applets would behave any differently.

  • Hi

    You try set backgroud-color, because this property is not set the controls under div can be accessed.


  • Hello all,

    I've tried it and it works ! Thanks a lot

  • thanks allot. I almost moved my wmv content to the place where it does not come in a way of website css menu. Now I do not need to worry about that issue and can place windows medial player content on top left side div on my website

  • Thanks for the iFrame info. It works great in some cases. Not to confuse anything, for the newer programmers out there you can always use the ol' standby of:

  • This may have been addressed in an earlier comment but I wanted to clarify.

    I am using an iframe under a floating div to display tooltips on a form with select boxes. The iframe is using the alpha filter for transparency in IE6, as the div has a bubble image with transparent sections. This works for most of the form, but the transparent section of the iframe overlapping the select boxes is white instead of transparent. Is this a known issue or am I overlooking something?

    Thanks!

  • That's known. I don't know of a workaround.

  • I was hoping that was not the case. :(

    Thanks for the quick response.

  • If you use Dojo Toolkit's "dojo.dialog" widget to display the popup div, they do all the work for you.
    Actually they use the IFrame solution.

  • @Naor: err, sure, as does the ASP.NET menu, the popup control in the Ajax Control Toolkit and many, many other similar components.

  • I can't figure out how to get this work! What am I missing?

    1. Create Dropdownlist
    2.Create iFrame
    3.Create div with matcing style...

    What else do I need to do...please help this is URGENT!

  • Hi egainey,

    Can you give us more information ? :)
    You can mail me at : fabien.molinet[you know what]gmail.com

    I'll help you.

    Best regards,
    Molinet Fabien

  • for the IFRAME SRC just use the most visited URL in the World about:blank


    Doesnt require any external Content and works in IE/FF and guess everywhere else...

    ^_^

  • @Kagran: as the post states, "if you work with a secure site (with an https: protocol), you can't use "about:blank" as the url of the iFrame, otherwise you'll get a warning from IE saying that the page uses both secure and insecure contents."

  • Thanks a lot for this neat little post. Helped me fix the bug like a charm...

  • Nice scripting, Life would have been much better if ms had fixed this bug, but at least there is a hack. All the more it makes me wish more people used firefox 2.x or higher

  • @Chuck: well, Microsoft *has* fixed this bug back in IE7.

  • Had the same problem with positioning a div over an text input box, but didn't want to use the iframe hack. It appears that if you set the backgroundcolor of the input to transparent, the problem is solved (only works if you don't mind a transparent input box).

  • @Roger: as far as I know, plain inputs don't have this problem, so it's possible that you were experiencing a plain z-index issue. If not, I'd love to see a repro (bleroy at microsoft). Thanks for the feedback.

  • I know that this is pretty old topic, but can't figure out how to cover windows media player object in similar way..

  • @romek: windows media player objects should be subject to the exact same fix.

  • it doesnt work for me if i put it in datalist

  • Thanks a lot. Very Useful

  • It is simple, just have a DIV mask then disable all the SELECT elements.

  • I can't figure it out, but as Zoro points out, there's a case when, on scroll of the main window, the select appears in front of the iframe. And then when you perform some action that requires rendering (e.g. drop down the select, or show an unrelated div, it returns to normal (i.e. iframe on top).

    I'm trying to isolate the cause in this js I've been given, but if you know of any reason why this might happen (why a scroll would cause the select to be rendered on top of an iframe), it would be mighty useful.

    Thanks.

  • @Zoro: you need to handle the scrolling event and reposition the iframe.

  • Perfect !!
    The iFRame covers my DropDownBox under de (popup div)
    Thanks a lot !!

  • ah nice one. if only we could rid computers of ie most of our compatability issues would be solved!

    thanks for this

  • Great post .... we are experiencing the odd IE6 behaviour where the select control shows thru if the page is scrolled. There are no background images on the page however. Setting the iframe size to 100% W and H or trying to set the iframe offset to match the scroll offset makes no difference. anyone come across other fixes?

  • @Chris: setting to 100% won't work. The whole point of the frame is that it should be the exact right size. What you need to do is capture the scroll events and move the frame with the page.
    But at this point in time, it might be a good idea to drop IE6 support altogether if you can afford it.

  • I want to check that is the div display is block or none with css anybody can help me

  • Thank you for this article. I hate to work on IE6 bugs and I really would like people to definitely get rid of it.

    Thanks again

  • Hi,
    I've been looking for a solution but didn't wanted to use iframe.
    I found that a div can appear over an input field on ie7, but the div has to come AFTER the input in the code.
    That's what i done and it works ; then with css i made it appear on my page on its right place.

  • @Pierre: the bug that the post is referring to is *fixed* in IE7. The problem in IE6 was that it was impossible without the iframe trick to put a div over a select.
    In IE7, the behavior is correct. The order in which the elements appear determine the default layering, but you can override that in CSS using z-index.

  • well given that 29% of all visitors use ie6 still (on my site) means i need to pay real close attention to bugs.

    i already went through 5 select/iframe/ie6/fix sites but my problem seems to be special. hopefully yours will get it right.

  • Hurray!!!

    You've done it! my dhtml popup now actually looks great

  • It's still working fine with the IE9 and Firefox 4+, not mention to latest chrome. I use this tactic to overlay a java applet, and it is working far better than any iframe shim method I've ever come across. Do not stop developing it.

  • i am trying to display pdf file in webpage in IE7 browser.but, when ever i am trying to scroll down the cursor ,the pdf content is overlapping on the headr part of the screen.

    i have used div and iframe.
    pdf file calling through the iframe and iframe is inserted in side the DIv Elemnent.

Comments have been disabled for this content.