Pixy-style CSS no-preload rollovers, with PNG support for IE

How it works

Most browsers see what is basically the same as Pixy's rollovers. The article explains better than I can, so I suggest having a read if it's not a technique familiar to you. Basically it sets the <a> tag to display:block, sets a pixel width, and uses a negative background-position on the :hover and :active states to shift the background image to display the correct bit..

So where's the problem?

Well, firstly, when trying to use an alpha-transparent PNG, it works fine in the majority of browsers, but as you probably know, and is well documented elsewhere, using PNGs in IE requires some extra effort to display transparent images properly.

But the biggest problem is when using IE's proprietary CSS to display a PNG, IE does not honour background-position. For that we'll have to cheat ;)

Hiding the background-image and getting everything ready for IE

If we use the IE specific CSS to allow it to display a PNG properly, but we also set the background-image, IE will display both (and ruin all our good work), so the first thing we do is hide the irrelevent CSS from IE using a Child-selector filter:

/* hide normal background from IE */
html>body #menu a		{ background: url("button.png") 0 0 no-repeat; }
html>body #menu a:hover	{ background-position: -157px 0; }
html>body #menu a:active	{ background-position: -314px 0; }

Apart from the CSS filter, the only real difference from Pixy's original implementation is the links themselves have been put into an unordered list, as we need another element outside the <a> tag in order to pull off our trickery.

Setting the transparent image for IE

In this example I've used Conditional Comments to hide the IE-specific CSS from other browsers (and the CSS Validator), I'll not go into details about that here though, read the article, or see this page's source ;).

#menu a{
	filter:	progid:DXImageTransform.Microsoft.AlphaImageLoader(src="button.png",sizingMethod="crop");
	height:	1px;
}

The most obvious thing there is the filter declaration, using the AlphaImageLoader to render the PNG. sizingMethod is set to crop, otherwise IE resizes the element to encompass the entire image.

There's also a sneaky height:1px, which is there to ensure the element has what Microsoft refer to as 'layout', without it the background image simply refuses to display. Fortunately (ish) IE handles height incorrectly, and will expand the element to fit it's contents regardless of the specified height.

Shifting the image on hover

Due to the fact IE does not honour background-position when using the AlphaImageLoader filter, we'll have to do something else:

#menu a:hover{
	margin-left: -157px;
	text-indent: 157px;
}
#menu a:active{
	margin-left: -314px;
	text-indent: 314px;
}

Using a negative margin, in combination with a text indent instead of the background-position allows us to move the container while leaving the text where it is.

Thanks

The Original no-preload css rollovers idea was originally concocted by Petr Stanícek (aka Pixy), from whom the basis for this example mercilessly stolen. The lovely background pattern courtesy of Squidfingers, Cheers lads.

And Thanks to my employer, Adestra Email marketing for allowing me to waste time on stuff like this ;)