21 Apr

IE7 "::before" jiggle workaround

Look at this page, in either Firefox, or IE5+. The curves are created using some handy pieces of CSS; ::before, ::after, and content().

Thanks to Dean’s wonderful project, IE7, that code works in IE5+, which meant that we could supply our own clients with curves that didn’t involve tortuous HTML.

However, if you refresh the example page a few times in IE (especially IE5), you will notice there is a time-lag between the page loading, and the curve showing. While this is acceptable for a small demo, it is not acceptable for a published site!

The problem is that the page, while loading, will position everything as if the curves’ space is not used, and then, after the IE7 script has done its thing, it will “jump” everything into the right place.

It can be very disconcerting to have that happen on every page that you visit in a site – to have the page jump around every time you load a new document.

So, I set about finding a solution.

The solution was relatively simple to find, once I knew what I was looking for – I needed to find a piece of CSS that IE5 understood, in order to “reserve” the space for the curves, and then override that CSS when the IE7 code had been loaded and run.

Using the example page as context, the hack would run like this:

 p.test { margin:30px 0  }
 body:first-child p.test { margin:0 }

That’s it, basically.

A CSS-compliant browser will apply the second line, as it is more specific than the first line. IE5+, though, does not understand the second line, so applies the first line. That has the effect of reserving the space needed for the curves, above and below the p.test.

When the IE7 script runs, it learns to understand the second line, so applies that, removing the reserved space. It also learns to apply the ::before and ::after code, thus placing the curves into the reserved area.

An example of that code in a live site can be seen here.