05 Jul

Handling :before properly in IE6

IE6 and IE5 do not support CSS2’s ‘:before‘. This is a pity, as it allows some pretty cool stuff to be done.

I’m currently working on an InkJet cartridge supplier’s website. One of the elements that the designer came up with is panels that have an interesting border effect at the top:

The image above is a screenshot taken with Firefox. The code to produce that effect was:

#columncenter:before {
    content:url(/extras/i/panelcorner.png);
    height:18px;
    display:block;
    background:transparent url(/extras/i/panelcorner.png) right top no-repeat
}
#columncenter{
    margin:0 180px;
    border:1px solid #8c8c8c;
    background:url(/extras/i/paneltopbar.png) top repeat-x
}

Note that there are three images mentioned. The two corner images are provided with the :before construct (you can use the same method to do rounded corners), and the background gradient is provided by the main element.

In order for the background gradient to show, it is important that the :before pseudo-element be truly transparent, as defined in the CSS. Unfortunately, the IE7 script cannot do this, as it was written to use object elements, which are not transparent in IE.

Here’s an IE screenshot. This is using IE7 0.8.

Note the big blank rectangle where a gradient should be. This is caused by the object taking on the background colour of the main element, but not the background image.

I had a fix for IE7 0.7, but it was not integrated with the master code. That’s a pity…

Anyway… Here’s a fix for IE7 0.8

In the recalc function in ie7-standard-p.js, replace the following code:

        // insert the pseudo element
        var $html = PseudoElement[$url?"OBJECT":"ANON"].replace(/%1/, this.className);
        var $$cssText = $generated.cssText;
        if ($url) {
          var $pseudoElement = document.createElement($html);
          $target.insertAdjacentElement($$position, $pseudoElement);
          $pseudoElement.data = _contentPath;
          addTimer($pseudoElement, $$cssText, Quote.remove($url[1]));
        } else {
          $html = $html.replace(/%2/, $$cssText).replace(/%3/, $content);
          $target.insertAdjacentHTML($$position, $html);
        }

With this:

        // insert the pseudo element
        var isImage=$url && /^url\([^\)]*\.(gif|png|jpg).?\)$/.test($content);
        var $html = PseudoElement[$url&&!isImage?"OBJECT":"ANON"].replace(/%1/, this.className);
        var $$cssText = $generated.cssText;
        if ($url&&!isImage) {
          var $pseudoElement = document.createElement($html);
          $target.insertAdjacentElement($$position, $pseudoElement);
          $pseudoElement.data = _contentPath;
          addTimer($pseudoElement, $$cssText, Quote.remove($url[1]));
        } else {
          if(isImage)$content=$content.replace(/url\(/,'<img src="').replace(/\)/,'">');
          $html = $html.replace(/%2/, $$cssText).replace(/%3/, $content);
          $target.insertAdjacentHTML($$position, $html);
        }
 

That’s it. Now, IE6 works, and we can code again using nice, standard CSS.

%d bloggers like this: