Shim technique in IE

In one of the projects I was working, we had an interaction where a DIV element pops up and demands some user action.

The DIV used to get obscured whenever it shows up over a select box in IE6 though i had applied a higer z-index compared to the select box on the page. One of my team-mates pointed me to a technique called “Shimming”.

I learnt that this problem apparently surfaces on browsers greater than IE 5.5 and happens when floated divs overlap with windowed control.

Now, the question is what is “windowed control”?

According to this KB Article, the various elements on a webpage can be classified as:-

Windowed Elements

  • tag elements
  • ActiveX controls
  • Plug-ins
  • Dynamic HTML (DHTML) Scriptlets
  • SELECT elements
  • IFRAMEs in Internet Explorer 5.01 and earlier

Windowless Elements

  • Windowless ActiveX controls
  • IFRAMEs in Internet Explorer 5.5 and later
  • Most DHTML elements, such as hyperlinks or tables

The article further says that -

All windowed elements paint themselves on top of all windowless elements, despite the wishes of their container.

However, windowed elements do follow the z-index attribute with respect to each other, just as windowless elements follow the z-index attribute with respect to each other.

All windowless elements are rendered on the same MSHTML plane, and windowed elements draw on a separate MSHTML plane.

You can use z-index to manipulate elements on the same plane but not to mix and match with elements in different planes. You can rearrange the z-indexing of the elements on each plane, but the windowed plane always draws on the top of the windowless plane.

The Shim Technique

To overcome this problem, this shim technique is pretty useful. In this technique, we use an absolutely positioned iframe of exactly the same size as the windowed element and below the windowless element which you want to have a higher z-index.

Typically, while creating an i-frame shim, we do it dynamically. The script snippet would look something like this:

var iframeShim = document.createElement( 'iframe' );
iframeShim.setAttribute( 'src', 'javascript:"";' );
iframeShim.setAttribute( 'frameBorder', '0' );

There are few provisos in the above code -

  • Make sure you follow proper case for properties like frame border, etc.
  • If your site is a secure site using the HTTPS protocol, then a mixture of http and https sites might give an error on IE.

Btw, the above snippet also makes sure that there are no additional http requests from the page.