IE6 Double Margin: A Simple jQuery Fix

by Andy Appleton

Among the many small irritations we have to contend with when developing a website for IE6 is the so called double margin bug.This bug causes floated elements to render with a double left margin. The bug is described here, and a solution here. Essentially the element must be forced to a state known as "has layout".

The Original Solution

The solution recommended is as follows:

The work around for this bug is preposterously simple, counter-intuitive and utterly in violation of the W3C recommendations—simply change the style of the floated element to "display: inline" and the problem disappears.

So do this--

<div class="box">
   <div class="sidebar" style="display: inline">content
   </div>
   content
</div>

A slightly cleaner way to achieve this is to create a separate ie.css stylesheet, and add a declaration looking something like this:

.myclass1, .myclass2 {display:inline;}

Cleaner still would be to enclose this ie.css stylesheet in a conditional comment so that it is only served to IE6:

<!--[if lte IE 7]>
<link rel="stylesheet" href="ie.css" type="text/css" media="screen" />
<![endif]-->

We can now add all of the elements which exhibit this behaviour to the CSS declaration, safe in the knowledge that it will only be seen by IE versions 6 and below.

A Simpler Way

This solution is good, but it does leave us with the problem of having to maintain a long list of id and class names in the ie.css file. A more straightforward way to deal with the issue would be to write a rule stating that all floated elements should also have display:inline; applied. Unfortunately this is not possible in CSS, but we can use a little JavaScript and RegEx trickery to achieve the same thing.

  1. This example uses the excellent and extremely easy to use jQuery JavaScript library, so the first step is to link to it in your page's <head> element:

    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>

    Note: I am linking to the Google hosted version of the library, you may prefer to host your own copy and link to that.

  2. Next we will create a separate ie.js file, and link to that in the <head> section of the page:

    <!--[if lte IE 7]>
    <script src="ie.js" type="text/javascript"></script>
    <![endif]-->

    Be sure to place this after the link to the core jQuery library.

  3. Into the ie.js file, we will add the following:

    // Initialise jQuery Regex...
    jQuery.expr[':'].regex = function(elem, index, match) {
        var matchParams = match[3].split(','),
            validLabels = /^(data|css):/,
            attr = {
                method: matchParams[0].match(validLabels) ?
                            matchParams[0].split(':')[0] : 'attr',
                property: matchParams.shift().replace(validLabels,'')
            },
            regexFlags = 'ig',
            regex = new RegExp(matchParams.join('').replace(/^\s+|\s+$/g,''), regexFlags);
        return regex.test(jQuery(elem)[attr.method](attr.property));
    }
    
    // ...and use it to overcome the 'double margin' bug. Add display:inline to all floated elements
    function double_margin() {
    	$(':regex(css:float, left|right)').css('display', 'inline');
    }
    
    // Let's go!
    $(document).ready(function() {
    	double_margin();
    });

    What we are doing here is:

    1. Telling jQuery that we plan to use regular expressions.
    2. Defining a jQuery function (double_margin()) which will search for every element which has float:left; or float:right; applied, and add an inline style of display:inline; to each
    3. Telling this function to fire when the document loads.

There we have it. A simple way to overcome the double margin bug by assigning display:inline; to all floated elements. It should be noted that this method will only work for users who have JavaScript turned on. For this reason it is probably wise to check your web stats before implementing this on a site.