Tuesday, August 14th, 2007
Work around the z-index issue with heavyweight IE components
<p>Brandon Aaron has developed a general work around for the common, nagging problem with IE6 and heavyweight components such as a select drop down ignoring z-index.Brandon created the background iframe (bgiframe) jQuery plugin which “provides a very small, quick and easy way to fix that problem so you don’t have to worry about it. No matter the size, borders or position the bgiframe plugin can fix it.”
In the simple case, you can grab a collection and call bgiframe on it: $('.fix-z-index').bgiframe();. You can also pass in data to mess with the top, left, width, height, opacity, and src parameters.
How does it work?
The bgiframe plugin works by prepending an iframe to the element. The iframe is given a class of bgiframe and positioned below all the other children of the element. In the default configuration it automatically adjusts to the width and height of the element (including the borders) and the opacity is set to 0. The element needs to have position (relative or absolute) and should have a background (color or image).
Check out the test page to see the plugin in action.
Related Content:











Does this solution handle rounded corners?
@Cameronw: I’d say yes, as the opacity is set to 0 (zero) you wouldn’t see anything underneith your rounded corners element.
oh, he reinvented the wheel
Most designers know they can use the iframe wedge, but having it a one-line implementation is nice.
You can find the docs for the plugin here: http://brandonaaron.net/docs/bgiframe/
“src : ‘javascript:false;’”
IIRC you’re going to have issues with that and IE7.
Check out
http://jqueryjs.googlecode.com/svn/trunk/plugins/blockUI/jquery.blockUI.js
To see how they got round the issue.
@JP: The hack is only applied in IE6 because IE7 fixes this particular issue.
Take back my IE7 comment, as this is clearly only needed for IE6, dowp, need more coffee. ;)
It does seem that this plugin will only work with items that are contained with a block level element, that fill the entire size of that elements.
So if you have a div inside a p tag and the div is absolutely positioned to float above it you can’t use this plugin to give it a background iframe.
I always liked the way they did this in Dojo, that the iframe and the node you want to screen can be unrelated in the DOM the iframe is just sized and slid under the node, seems to give much greater flexibility.
Great and so simple, thanks!
@JP: Hmm … It looks like Dojo injects their background iframe into the parent element, same as bgiframe. http://trac.dojotoolkit.org/browser/dijit/trunk/_base/popup.js#L221
Also, why are you putting a div inside a p tag? That is invalid HTML.
Good work, but I wanted to throw out an idea to the js framework community. Why not deal with the dropdown/absolute div problem by attacking the dropdown instead of the absolute div? I realize just about framework out there has dealt with the problem by “fixing” absolute divs with iframes, but what if we left absolute divs alone, and “fixed” the drop down component, i.e. built a custom drop down component with DHTML that doesn’t show up in front of absolute divs? In order to maintain graceful degradation, one could scan a page for selects in IE6 and change them to a DHTML dropdown. You could probably use the same code across multiple frameworks even. Maybe I will do this sometime, but just wanted to throw this out and see what you think, see if anyone is interested in such an idea.
I am not a big fan of the iframe hack, it is can be a big performance hit, and I have seen some stabillity issues with it as well (maybe they have been resolved). Even though I don’t enjoy the hack, good work with the implementation of it Brandon, I know it is not trivial.
@Kris: Thanks for the kind words. There are several combo box implementations out there already. For example Ext provides a really nice combo box to replace the native select form control.
Go to: http://extjs.com/deploy/ext/docs/
and the click on Form and ComboBox in the left side bar.
@Kris
An iframe is a much more simple solution as it only requires a single element and a couple lines of CSS vs a fairly complex JavaScript widget. Also, you would no longer have the benefit of native OS controls.
Always putting an iframe behind every absolute layer is bounded with some actions like resizing and positioning. This could be a performance killer in some webs and actions like a mouseover for example. Surely a matter of layout. But it’s also a nice way to ignore some unwanted dropdowns, if it’s only a “window” layer doing nothing more than laying over some content. A flash application layer for example.
In related news: Firefox 3 will have the Mac/Firefox scroll bar bleed through bug fixed. https://bugzilla.mozilla.org/show_bug.cgi?id=187435
will the iframe have unwanted side effects to BackButton-Fixes like StateManager
http://exanimo.com/javascript/using-the-statemanager-in-ajax-apps/
?
@Jan Mentzel: Not it will not affect the usage of the back button or the back button fixes.
“Also, why are you putting a div inside a p tag? That is invalid HTML.”
Just because it’s invalid doesn’t mean it’ll happen (there are occasions where people have write JS for the HTML they are given), how about an img tag inside a p that has display:block, position absolute (I see that often).
The Dojo code you link to is the 0.9 version, I was referring to the code in 0.4.3 at:
http://trac.dojotoolkit.org/browser/tags/release-0.4.3/src/html/iframe.js
It was only a suggestion, to help make the plugin more flexible :-)
@JP: Maybe I’m missing something but that is still appending the Iframe to the node just as the bgiframe does. http://trac.dojotoolkit.org/browser/tags/release-0.4.3/src/html/iframe.js#L41
The case where you talk about a div inside a p tag, the bgiframe will work for that div or for the p tag. However, the p tag with an image inside is a different story. The image would need to be wrapped with another element for the bgiframe to work. Thanks for the feedback and the idea of just positioning the iframe under the element is an interesting approach.
http://erainfo.blogspot.com/2004/09/mostrar-um-div-sobre-um-select.html
Looks the date.
this is old plugin, and old news.
why post about it now?
It’s too bad this doesn’t include further info for IE7 – as there STILL exists issues with ActiveX objects (yes, unfortunately). Relative positioning is problematic, as is the click to activate issue. All together, IE7 still bonks depending on configs.
Done better here:
http://www.hedgerwow.com/360/bugs/activex-listbox/demo.php
and Here:
http://www.hedgerwow.com/360/bugs/css-select-free.html
I really think it’s high time Microsoft fixed this problem.
IE7 be damned, IE6 is still one third of the market and therefore a massive thorn in everyone’s side. MS have bazillons of dollars, the fix is already written, they will just stubbornly not apply it to IE6.
Microsft you evil mongrels, FIXIE6!
That and li:hover
see also IframeShim for Mootools: http://clientside.cnet.com/wiki/cnet-libraries/01-browser-fixes#iframeshim.js
Note that this practice is not new:
http://www.macridesweb.com/oltest/IframeShim.html (2003)
Very useful plugin. It fixed a lot of my code for IE just in moment.
However, to make it more friendly for me, I’ve added a no-scroll behavior too in the plugin code:
iframe … scrolling=”no”class=”bgiframe”frameborder=”0″…
Thank for the useful tool!