Cross browser alpha transparent background CSS (rgba)


In building theĀ BBC Programmes website the design called for various layers of semi-transparent coloured boxes. These colours can change depending on the programme (for example: Never Mind the Buzzcocks) so an alpha transparent PNG is not a maintainable option.
Obviously the simplest method is RGBA.

#div {
    background: rgba(0,0,255,0.7);
}

As elegant as that is, it is not currently an acceptable solution in it’s own right. RGBA is not supported in Internet Explorer below version 9. Of course the BBC needs to support the majority of it’s visitors. The phrase “it doesn’t need to look the same in every browser” could be thrown about, but in this case the semi-transparent boxes are quite essential for the look desired.

So, as any good web developer does, I turned to Google. I thought it would be a simple query (expected it to use IE filters) but it took unusually long to find it. Eventually I arrived at this blog post which proved helpful.

Alpha-transparent background code (quoted)

.alpha60 {
	/* Fallback for web browsers that doesn't support RGBa */
	background: rgb(0, 0, 0);
	/* RGBa with 0.6 opacity */
	background: rgba(0, 0, 0, 0.6);
	/* For IE 5.5 - 7*/
	filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#99000000, endColorstr=#99000000);
	/* For IE 8*/
	-ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#99000000, endColorstr=#99000000)";
}

BUT

There appeared to be a problem with this once we saw it in the wild. First you have to add zoom:1 to make it work in IE6-7 but this isn’t unusual. Secondly IE8 didn’t seem to work. As IE8 does support rgb() as a background colour the result is a solid coloured box.

Therefore we need to set the background back to transparent after the rgb rule (just in IE8 and below). After more Googling the answer was the backslash 9 hack.

Using that and tweaking (a lot) produced the following block of code. Note the -ms-filter line supported as IE8+ has been removed as it unnecessary. We have to use the non prefixed version anyway (for IE6,7) so the code is no more valid by using it in this scenario

#div {
    background:rgb(255,0,0);
    background: transparent\9;
    background:rgba(255,0,0,0.3);
    filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#4cFF0000,endColorstr=#4cFF0000);
    zoom: 1;
}

This fixed the transparency problem but there was a new issue. Internet Explorer 9 is capable of displaying rgba AND the filter property. This creates a doubling up of the transparency and ruining it’s effects. It appears there is no CSS attribute hack that targets only IE8 or IE9 and not both (that has been discovered yet).

The ideal solution here is to not use the filter in IE9. The CSS filters are memory intensive and since IE9 is fully capable of rgba, it should be rewarded as such. IE9 is capable of many CSS3 selectors so we’ll use one here:

#div:nth-child(n) {
    filter:none;
}

This is a valid CSS selector that will match all elements in the same way as if it was not here. More detail on how nth-child works.

This page shows various test scenarios

Full code

#div{
    background:rgb(255,0,0);
    background: transparent\9;
    background:rgba(255,0,0,0.3);
    filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#4cFF0000,endColorstr=#4cFF0000);
    zoom: 1;
}
#div:nth-child(n) {
    filter: none;
}

So that’s the code required. I’ve put it here as a complete solution to save other developers having to search and test as much as I had to. Of course it’s recommended to use conditional classes instead but sometimes that’s just not possible.

The only other thing that slows down creating alpha transparent backgrounds is the conversion from hex -> rgba and opacity -> hex so below is a handy converter. Enter a hex colour and opacity value and it’ll spit out the code in the form seen above.

I’ll accept any tweaks/improvements in the comments.

Share this post