How we deal with browser quirks, with a compendium of IE 7 issues

Anyone who has done serious DHTML development work knows there are many issues and quirks with the browsers out there. Of course, we had to come up with a way to deal with these cleanly for OL 4. First, I'll talk about how we deal with browser quirks. Next, I'll list the IE 7-specific issues we ran across during development of the OL4 DHTML runtime.

Capabilities-based browser quirks

1. We keep an object that lists each quirk by name, with a boolean value for whether it's active in the current browser or not. Here's a list of all the current quirks, with default values:

LzSprite.prototype.quirks = {
    fix_clickable: true
    ,fix_ie_background_height: false
    ,fix_ie_clickable: false
    ,ie_alpha_image_loader: false
    ,ie_leak_prevention: false
    ,invisible_parent_image_sizing_fix: false
    ,emulate_flash_font_metrics: true
    ,inner_html_strips_newlines: true
    ,inner_html_no_entity_apos: false
    ,css_hide_canvas_during_init: true
    ,firefox_autocomplete_bug: false
    ,hand_pointer_for_clickable: true
    ,alt_key_sends_control: false
    ,safari_textarea_subtract_scrollbar_height: false
    ,safari_avoid_clip_position_input_text: false
    ,reverse_mouse_wheel: false
    ,no_cursor_colresize: false
    ,safari_visibility_instead_of_display: false
    ,preload_images_only_once: false
    ,absolute_position_accounts_for_offset: false
}

2. Next, we use some browser detection code to turn specific quirks on or off depending on the browser we're running in:

    ...
    if (Lz.__BrowserDetect.browser == 'Opera') {
        // Fix bug in Opera where if any parent of an image is hidden the size is 0
        LzSprite.prototype.quirks['invisible_parent_image_sizing_fix'] = true;
    }
    ...

3. Finally, the sprite checks these quirks at runtime, like so:

LzSprite.prototype.__imgonload = function(i) {
    ...
    if (LzSprite.prototype.quirks.invisible_parent_image_sizing_fix) {
        Fix...
    }
...
}

This has a several benefits:
+ By conditionalizing on capabilities (instead of browser-specific version information) we can turn the quirks on or off once up front when we do the browser test.
+ It runs faster - it's quicker to test for a boolean value than test for a browser ID/version each time a given chunk of code runs.
+ We can easily and safely turn behavior on or off without touching the rest of the code.
+ Quirks can be cleanly reused when the same issue is discovered across multiple browsers. For example, when I discovered Opera had the same issue as Webkit (images with any parent div whose style.display is set to 'none' don't get valid height and width properties), all I had to do was set the 'invisible_parent_image_sizing_fix' quirk to 'true' for Opera in the browser detection phase. When this issue is fixed in future browser versions, I can easly turn the quirk back off.
+ The rest of the code is much cleaner because the quirks are 'self-documenting'. Compare these two for legibility/maintainability:

    if (this.quirks.invisible_parent_image_sizing_fix) {
        ....
    }

vs.

    if (browser.name == 'Opera' || (browser.name == 'Safari' && browser.version < 1.5)) {
        ....
    }

I encourage everyone to steal this idiom and apply it to their code! It'll make the DHTML world a better place. If only we didn't have to worry about these issues...

Then again, if you use OL 4, we'll worry about them for you! We're fond of saying 'we work hard so you don't have to.' :)

IE 7-specific quirks

Okay, on to the second part of the article: IE 7-specific quirks. The IE team is currently in the process of locking down features for the next version of IE. This provides an excellent opportunity for us to list the IE-specific bugs and quirks we ran across during the development of the DHTML runtime for OL 4.

I'm not trying to single out IE here - I intend to talk about quirks in other browsers (there are plenty) in the future. I just learned the IE team is soliciting feedback, and I wanted to provide some in a timely fashion! So, I'll list only issues that affect IE 7 for now:

+ Can't set opacity on any div that contains <input type="text"/> or <textarea/> without getting nasty visual artifacts in the text field.

+ Must use the AlphaImageLoader if we want opacity to apply to a div and all its children.

+ AlphaimageLoader must have its src property set to the URL of an image to prevent a red x/missing image icon from appearing

+ AlphaimageLoader does not send onload/error events - instead we have to use the img tag mentioned above

+ IE 7 still has memory leaks for apps loaded in iframes

+ Empty divs with style.backgroundColor set appear ~10px tall unless they contain an img (for less than 2px tall) or have style.fontSize = '0px' applied.

+ IE does not support &apos; when setting a div's innerHTML property

+ IE does not send onclick/onmouse* events for divs without a blank image attached

Thanks for all the hard work on IE 7 - it's miles ahead of IE 6 in almost every way. And we all love the IE developer toolbar! Of course, let me know if you need more specifics about any of these.

Best of luck, and I hope some or all of these issues can be addressed in an upcoming release!

11 Responses to “How we deal with browser quirks, with a compendium of IE 7 issues”

  1. Jim R. Wilson (jimbojw) Says:

    I think you’re on the right track by abstracting out the browser quirks, but I _hate_ that you’re doing “Browser Detection” instead of “Quirk Detection”. It’s cool to check if an object supports the “addEventHandler” method for example, while it’s bad form to check “is IE”.

    Also, by naming your quirks with the offending browser (such as “fix_ie_background_height”), you’re forcing the implementing methods to know about browser quirks down to the “which browser has this” level. IMO, separation of concerns dictates that the checking methods need not know or care which browsers suffer from which quirks.

  2. Max Says:

    @jim,

    Strong points! You’re absolutely right about Browser detection vs. quirk detection - I avoid browser detection wherever possible. Unfortunately, most of these quirks are things that are difficult to detect with quirk detection, like which direction the mousewheel reports it’s moving. Or, they’re so tied to a specific browser (like AlphaImageLoader is to IE) that I found it more expedient to do browser detection. I’m so used to checking for browser quirks elsewhere (document.all for example) that I never bothered to follow my own advice and pull these tests out into quirks with explicit IDs. It never occurred to me to do this until I was writing the post yesterday - funny how writing about things often clarifies the one’s understanding!

    And, you’re absolutely right about how quirk names shouldn’t be named after the browser! This is something that occurred to me, but I ran out of time before 4.0 and it’s seemed like a low priority since.

    Thanks for the feedback - I really enjoy blogging this stuff because of the quality comments I get from folks like you!

  3. evden eve nakliyat Says:

    very nice informations…thank you very much.mr solak not salak…

  4. Ajax Girl Says:

    [...] Max Carlson of OpenLaszlo recently blogged about their approach to dealing with browser incompatibilities: [...]

  5. Johan Sundström Says:

    From the way you use the prototype objects above, it looks like you ought to put the quirks mapping directly onto LzSprite rather than its prototype object, or you’re just penalizing yourselves with a pointless extra lookup every time you peek for quirk compensation like this.

    Or maybe you do check for them in this.quirks rather than LzSprite.prototype.quirks?

  6. naterkane.com» Archive » IE7 Quirks Says:

    [...] Max over at OpenLazlo was writing about some browser/quirk detection that he put together for v4.0. He listed in his post a number of quirks for IE7, some of which I was aware of, and some I wasn’t. [...]

  7. Cloudy Thinking » Blog Archive » How OpenLaszlo Handles Browser Quirks Says:

    [...] Ben Galbraith wrote about Max Carlson of OpenLaszlo who recently blogged about their approach to dealing with browser incompatibilities. [...]

  8. Max Says:

    @Johan,

    You’re absolutely right! I use this.quirks whenever I’m in the sprite’s scope. The example above is actually in the onload handler for an image, so the scope is an image object. If anyone’s curious, here’s a link to the sprite source.

  9. Painfully Obvious » Blog Archive » Capabilities vs. Quirks: a look at browser sniffing Says:

    [...] Max Carlson (of OpenLaszlo) recently wrote about his toolkit’s approach to browser quirks, reminding me of a great Dev.Opera article on capability detection. [...]

  10. links for 2007-04-06 at Notes from a messy desk Says:

    [...] OpenLaszlo Project Blog » How we deal with browser quirks, with a compendium of IE 7 issues Now that’s the right way to deal with browser quirks. Much more readable code because I can (as a non-JS-guru) now figure out why you’re doing all that apparently useless code! (tags: javascript quirks bugs browsers ie firefox opera) [...]

  11. Jay Freeman (saurik) Says:

    + IE does not support ' when setting a div’s innerHTML property

    This is actually correct behavior. In fact, it is one of the few things that IE has consistently gotten right throughout the years that other browsers have not: ' is _not_ valid HTML.

    Please read: http://fishbowl.pastiche.org/2003/07/01/the_curse_of_apos