css transparency issues

Transparency is a delicate issue in css. Even though most browsers support the use of css transparency (through the opacity property), it remains troublesome to apply it in most cases. Furthermore, ie8 seems to have its own set of problems dealing with transparency. This post will offer a simple alternative to avoid common problems and will tell you how to deal with ie8 to achieve better results.

For more information about basic transparency issues, including ie6 fixes and FF2 quirks, I'll simply refer to my previous article on css transparency. Today's article can be seen as an addition to that, providing a couple more alternatives and digging up new Internet Explorer issues.

transparency rules, css transparency sucks

The biggest problem with css transparency remains its basic implementation. Setting the opacity property will make everything inside the targeted element transparent. Text, images and even nested html ... the whole deal will receive an alpha filter. While this is the desired result in a select number of cases, usually you just want the background of an element to be transparent. And even though behavior in the different browsers is pretty consistent when it comes to the opacity property, it is not much comfort considering the effect it has. Luckily, there are two main options to avoid this behavior.

first example on the test page

using rgba color

.opaque {background:rgba(255,255,255,0.5);}

Since a while support for rgba color has been pretty good in modern browsers. The newest versions of Firefox, Safari, Opera and Chrome all support this css value. The rgba color value is pretty much the same as the rgb value, only with an added alpha channel providing the transparency. This is a much better concept than the general opacity property, since we can chose which elements we want to make transparent. The rgba value can be used for all colors (including text colors and background colors), allowing you to specify different alpha values for each element. Nested elements won't be effected, achieving a result most of us will be aiming for.

The example above illustrates the use of the rgba value. There is no hex shorthand, so it's a little trickier for those used to working with hex colors, but the effect is pretty neat. Of course, Internet Explorer missed the boat. Even ie8 doesn't support the rgba values yet.

second example on the test page

using transparent pngs

.opaque {background:url("img/white-50.png");}

A different approach is using a transparent png for the background. That way, only the background color will be transparent, all nested elements will still be solid, including the text in the base element. It's a surprisingly easy method with very good results. Works fine in all browsers, even in Internet Explorer. Only ie6 won't support this method since it can't handle transparent pngs. You could use the png workaround for ie6 or just lift the transparency for ie6 users. Since transparency is usually a visual touch up, they should be able to do without.

Only drawback of this method is that it's a bit harder to implement since all the action happens in your graphic software. A pure css solution would be better, sadly in most situations the available css options just won't do.

third example on the test page

ie8, transparency and hovers

Not too long ago I was implementing a horizontal navigation with a transparent background. Since the transparency was ever so slight, using the opacity filter was not a big deal. The hover state on the links simple changed the background color defined on the link. All worked well, except ie8 wasn't showing the hover state. When I finally stopped sighing and cursing I tried a few of the basic fixes.

.base {filter:alpha(opacity = 50);} .base a:hover {background:#f00; position:relative; filter:alpha(opacity = 50);}

Placing a zoom:1 on the hover state didn't do much, so I started experimenting with pos:rel. To my surprise, the hover state showed, but broke the transparency for ie8. Adding another transparency filter worked but created (of course) a different color. You could use another hover color which in theory should give you the same effect as in other browsers, though I'm afraid this involves a lot of trial and error.

I've seen a couple of mentions of this bug on the web, but without any definite replies or solutions. Even though the one above is hardly perfect, it beats having no hover effect at all. If better solutions exist, I'd be glad to hear about them.

check out the test page with ie8


As you can see, there's still a long way to go before css transparency becomes a reliable way to style page elements. It's already here and it can be used, but chances are you'll run into some kind of trouble sooner or later. Just another day in the life of a csser.