Adam Perfect

General

Internet Explorer 6, transparent PNGs and absolutely positioned child elements

... or how IE6 yet again drove me close the point of insanity.

IE6 is notoriously useless when it comes to transparent PNG images, with Microsoft inexplicably never having added support for the file format in all these years. As such, web developers who want to get fancy with their transparency (hey, that rhymes!) have to use a work-around based on IE-proprietary CSS filters.

At the basic level, you need to apply the AlphaImageLoader filter to any element that's using a transparent PNG so that IE6 reloads the image with proper alpha channels (the transparency bit):

#my_box { filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='/images/transparent_thing.png', sizingMethod='crop'); }

Drew McLellan's 24 Ways article is a great read on how the problem works along with the general solution and a link to probably the best JavaScript-based solution, SuperSleight.

Working on a layout for my Dad's new company this week, I needed to use a lot of transparent PNGs. The SuperSleight script did the job well at replacing all the images in IE6, apart from a couple that were repeating background images - there's no way at the moment to repeat transparent PNGs in IE6 - that were fixed in one instance by making sure SuperSleight didn't do anything (no transparency involved) and in the other by having to just make a really huge version of the image so it didn't need to repeat. Not ideal, but IE6 rarely is.

Drop-down menu exampleThe real problems started with two drop-down menus at the top of the page. Each has a large, transparent PNG background image on the 'trigger' area, with a menu appearing over and below it on mouseover. In IE6, once the AlphaImageLoader filter has been applied, the browser won't let eny child element expand outside of the 'box' of the parent element, as if it had overflow:hidden applied (which it doesn't).

This meant that the drop-down menu would be cut off just below the 'Login' link in the image above. After a couple of days banging my head against a wall, trying all kinds of things with z-index and other styling solutions, I've been reduced to JavaScript hackery. Given that I'm already having to use JavaScript to make the menus work in IE6 anyway (thanks, lack of :hover pseudo-class on anything but a elements!), I decided to see if just expanding the height of the parent div (the one with the background image) would work.

It did. I feel dirty doing it, but if in IE6 you just expand the height of the newly-constraining parent div whenever the child menu is showing, you can finally see the drop-down menu in full. Here's the JavaScript I'm using for the menu now:

var userMenu = Behavior.create({
    onmouseover: function() {
        $('menu1').addClassName('show');
        var menHeight = $('menu1').getHeight() + 60;
        if (Prototype.Browser.IE) {
            this.element.style.height = menHeight+'px';
        }

    },
    onmouseout: function() {
        $('menu1').removeClassName('show');
        if (Prototype.Browser.IE) {
            this.element.style.height = '90px';
        }

    }
});
Event.addBehavior({ 'div#header div#user' : userMenu });

The important bits are in bold. On mouseover, the JS calculates the height of the sub-menu and adds that to an (unfortunately for the moment) hard-coded height to account for positioning relative to the parent and sets that as the new height. On mouseout, the parent element's height is reset. This code is using prototype.js (for the $ functions, etc.) and lowpro.js (for the unobtrusiveness).

If anyone knows of a proper solution to this ludicrous IE6 bug, please let me know!

Written by Adam on

Adam is a Director of User Experience by day and photographer as time allows.

You may also like…