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!

iPhone development and CSS3

I just bought an iPhone and so, naturally, being a web developer I've started looking at what can be done with iPhone apps. Having a look at one of Apple's demos (iPhoneButtons) reminded me that of course you only have to develop for Safari on the iPhone and therefore can use some of the nifty CSS3 features that are already available in Safari.

Developing iPhone interfaces might be an interesting way to get to grips with a few CSS3 features where in a normal web project you wouldn't want to use them yet.

Live re-design time!

Following a recent trend for 'live re-designs', I've rashly (it's 1.15am) decided to start re-designing this website in its live state.

What that means for tonight is that I've replaced the stylesheet with a super-basic one, including the reset.css and typography.css files from the Blueprint CSS framework for a quick-start on the whole vertical rhythm thing. I couldn't quite bare to quite leave it at that though, so I've quickly made sure the flickr 'badge' at least displays back up at the top of the page where it was along with the main links. Totally untested in anything but Firefox 2 for now though.

The idea (or at least part of it) is that by having your live website showing all the progress (or lack thereof) while re-designing encourages you to get a move on and get something done.

We'll see :)

We're hiring

At Gottabet we're looking for a 'web application designer' to join the team. The job entails a range of web dev, from helping design various sections/features of the website to implementing them in HTML and CSS.

There's a full job spec on the website, so if you're a developer who's big on web standards looking for an exciting, fast-paced job working on a big social website, check out the job spec and get in touch with Wim and Bertrand (email addresses on the linked page).

IE6 and position:relative (aka: 3 wasted hours of my life)

At Gottabet, we've started to migrate the website to a cleaner, wider layout that I've been working on for the past few months. We started by launching a new homepage and a couple of weeks ago we trialled a new signup page (via A/B test) and then rolled that out for everyone. Yesterday we launched our new Bet Detail Page. This week I'm working on getting a number of the 'basic' pages ported over and after a great start hit one of the most frustrating IE6 bugs for some time.

Absolutely-positioned button over a bet imageOn Gottabet we often absolutely position a 'Bet on it!' button over a bet image in listing pages - so it sits on a corner of the image. Most of the time this works absolutely fine - you have a div containing the bet image and the 'bet on it' link. The div is styled with position:relative and the 'bet on it' link is position:absolute, with the necessary top, left, right or bottom spacings for wherever it needs to sit compared to the image.

For the one page I was working on today though, it all went wrong. Very, irritatingly, wrong.

The problem: relatively-positioned elements on the page would move from their correct (effectively inline) position in IE6 and shift down a hundred pixels or so and right a bit. To confound matters further, I found that it depended on whether I refreshed the page while looking at the top or the bottom of the page in the browser. When scrolled to the top, the relative elements moved down on refresh. If scrolling to the bottom of the page and hitting refresh, on reload they'd be too high.

After searching for known issues with IE6 and position:relative, I found a couple of common problems that didn't seem to apply to me: the peek-a-boo bug and hasLayout.

The hasLayout issue seemed close, but the div with position:relative was already triggering hasLayout thanks to having a specified width and float:left. The symptoms also didn't quite match up (mine seemed much weirder). In the end, I resorted to what I should have done much earlier and set up a test page with an extremely stripped-down verson of the page content - only the bare minimum of the grid layout with no header/footer and only the CSS relevant to the part of the page that was breaking.

It worked fine. This was a good sign, because it at least meant there was definitely something causing the problem, so I started adding code (and the relevant styling) back in until it broke. Turns out a containing div had position:relative on its own, with nothing to trigger hasLayout in Internet Explorer. It didn't affect the case where it was being used, but by the time it filtered down to the next relatively-positioned block things were going crazy.

After 3 hours (most of them going round in circles before I started the stripped-down HTML version - there's a lesson), all it took was adding a width to that containing div to trigger hasLayout in IE and all was well once more.

So be warned: the hasLayout bug gets nastier when you have nested blocks using position:relative!

 1 2 3 4 Next →

About

User