September 26, 2007

AJAX can be really useful sometimes. We all agree on that. We’ve pretty much solved the cross-browser divide when it comes to the XHR object by using libraries, but one thing still remains – what about the GUI?

I know this might seem like just another post about using AJAX and fancy GUI updates, but let me point out that it isn’t. It’s about a major error I’ve found in IE7 (and possibly 6) that kinda blows your whole client-side dynamic updates. I’m talking about rendering errors regarding lists in IE. The dynamically rendered ones.

A test case involves an unordered list (possibly ordered, too), which is empty by default (on page load) and gets populated after the AJAX request fires. What my script did was it took a JSON response and appended li elements to the list. You’d think something as simple as this would pose no problem to the new and improved Trident, but it does. The list expands as though the list items are there, but they’re transparent. If you want to see the contents, you have to drag a selection over the text (and even then renders only the letters that were actually selected), but they dissapear upon re-rendering.

The first solution I could come up with is to apply a CSS transformation to the text after adding li elements. Which is a major pain in the ass. I just did a quick .fadeOut(1).fadeIn(1) to force change in opacity:

// lang javascript
jQuery("ul.error").fadeOut(1).fadeIn(1);

That way, no blinking would be noticed by the user since the animation would be faster than a screen redraw, thus eliminating the problem.

Haven’t done a baseline test on this one, but it shows just how grimey stuff gets when you’re not developing straight onto IE7 in the first place, then porting to others.

Long live Trident. You bastard.

UPDATE: I’ve managed to identify the culprit causing this disastrous behaviour – it has to do with floated elements and clearing elements. Also known as the Peekaboo bug. While this solution might not be appropriate for you, it worked for me in the given situation.

Basically, this problem manifests itself when you try to use floats, then a clearing element after them to ensure they are fully contained within a parent container div. The problem is solved by assigning the following style to the clearing element:

// lang html
<div>&nbsp;</div>

The only problem here I can see is that it breaks pixel accuracy – while you can assign padding and margin of 0, you cannot style it with height:0 or font-size:0. And also, adds to the semantics of the page, which I personally dislike. Sure, you can class the style in the above example, but you still need to put a non-breaking space in there.

This was supposed to be fixed in IE7, as the link says. Guess not. (Tested on IE 7.0.5730.11, update version 0, Windows XP SP2 fully patched.)