CSS Opacity: A Comprehensive Reference

CSS opacity has been a bit of a trendy technique for a few years now, and it’s been especially frustrating for developers trying to implement opacity (also referred to as CSS transparency) in a cross-browser fashion, because it’s taken a while for the different browsers to finally agree on settings. There is still not a universal method to ensure opacity settings work on all currently-used browsers, but things have improved in the last little while.

This reference is going to provide a detailed overview of CSS opacity, along with some code examples and explanations to help you implement this useful CSS technique in your projects equally across all browsers.

Old Opacity Settings

Here are the old opacity settings that were required for older versions of Firefox and Safari:

#myElement {
-khtml-opacity: .5;
-moz-opacity: .5;
}

The -khtml-opacity setting was for older versions of the webkit rendering engine, and was necessary in order to get older versions of Safari to work. This proprietary property is now obsolete and is no longer needed unless you know that you have a significant amount of web traffic coming from visitors using Safari 1.x., which is highly unlikely.

The next line uses the proprietary property -moz-opacity, which was aimed at very early versions of the Mozilla rendering engine, and dates back even to Netscape Navigator. Firefox stopped requiring the -moz-opacity property since Firefox 0.9. Firefox 3.5 (now using the Gecko engine) has dropped support for this property.

CSS Opacity in Firefox, Safari, Chrome, and Opera

Here is the simplest and most up to date syntax for CSS opacity in all current browsers except Internet Explorer:

#myElement {
opacity: .7;
}

The syntax above will set an element to 70% opacity (or 30% transparency). A setting of opacity: 1 would make the element opaque, whereas a setting of opacity: 0 would make the element completely invisible. This is easy to remember if you keep in mind that the word “opacity” comes from the word “opaque”, which is the opposite of “transparent”. The lower the opacity (or “opaqueness”), the closer you’ll be to transparency.

The opacity property can be set to two decimal places, so a value of “.01″ would be different from a value of “.02″, although the visible difference would be very hard to notice. Generally, it’s best to stick to one decimal place, using values like “.3″ or “.7″.

CSS Opacity in Internet Explorer

As usual, Internet Explorer doesn’t play well with others, and since there are currently three different versions of Internet Explorer in common use, the transparency settings are different, and sometimes require additional CSS to get them to work.

#myElement {
filter: alpha(opacity=40);
}

The above css uses the proprietary filter property to get transparency to work in Internet Explorer versions 6-8. There is one caveat for IE6 and IE7: In order for the transparency settings to take effect, the element in question needs to “have layout”. An element can be given layout using a number of CSS properties, including width and position. For details on the Microsoft-only hasLayout property, and how to trigger it, see this article.

Another way to set transparency via CSS in Internet Explorer 8 uses the following syntax (note the comments that indicate which versions):

The first line will work in all currently-in-use versions of IE, and the second line works only in IE8. Notice the differences between the two lines: In line two, there is a -ms- prefix attached to the filter property, and there are quotations around the entire value declaration, both of which are necessary for that syntax to work.

To be honest, I really have no idea why you would even need either of the “progid” methods, since the filter property works on any element that has layout in all versions of IE using the syntax alpha(opacity=40), as shown in the first example in this section.

Update: Evidently, in order to get IE8 in compatibility mode to recognize opacity settings, you need to do the following, in this order:

Basically, if you’re including the IE8-as-IE7 meta tag in your site’s code, or you’re worried that IE8 users will be hitting the compatibility mode button, then this would be necessary. Otherwise, just use the plain filter method (first example).

Thanks to the comment by Peter for providing the source for this info. I haven’t actually tested to confirm this, but the referenced website is quite reliable, so I will assume it’s correct.

Setting and Changing CSS Opacity with JavaScript

You can access the CSS opacity property in JavaScript using the following syntax:

The above lines of code could be used inside of a loop or other dynamic function that alter the values in an incrementing fashion. Of course, you would first identify the client capabilities using feature detection in order to decide which line of code to use.

Setting and Changing CSS Opacity with jQuery

Setting CSS opacity directly using jQuery is much more practical and easier to implement, because the code is exactly the same for all browsers, and you don’t have to worry about an element “having layout” in IE:

Whatever the opacity of the element is when the animation begins, it will animate until it reaches an opacity level of “.4″. The speed of the animation is set using the value “1000”, which is the duration of the animation in milliseconds. The final property listed is an optional callback function that will run some code when the animation is complete.

If the opacity of this element is already set to “.4″ in the CSS, then you won’t notice any difference when the animation runs, so the animated value has to be something significantly different.

Transparency Through RGBA

Another CSS3 technique that is supported by a few newer browsers (namely Firefox 3+, Opera 10.1+, Chrome 2+, Safari 3.1+) is setting opacity by means of an alpha channel in RGBA. Here is the syntax:

#rgba {
background: rgba(98, 135, 167, .4);
}

In the above declaration, the background is given a color in RGB (the first three numbers), then an alpha setting is given last, to implement transparency on the given color. This alpha setting works the same way as the opacity property, with any number accepted from 0 to 1, up to two decimal places. The higher the number, the closer the color will be to full opacity (opaqueness).

Transparency Through HSLA

Similar to the previous declaration, CSS3 also allows the ability to set a color along with an alpha value using HSLA, which represents Hue, Saturation, Lightness, and Alpha. Here is an example of HSLA transparency:

#hsla {
background: hsla(207, 38%, 47%, .4);
}

For a further explanation on HSLA colors, see this article on W3.org. As is the case with RGBA transparency, the last number represents the transparency setting, and works the same way as RGBA.

One important benefit to note about both RGBA and HSLA transparency is that these transparency settings don’t affect child elements the way the opacity property does. The alpha setting for RGBA and HSLA affects the opacity of the background color only and nothing else (thanks to Irakli for pointing this out).

Effects on Validation of CSS

If you’re using any opacity settings in your CSS, your CSS code will not validate according to current W3C standards. Many developers are not as concerned about CSS validation as they are about HTML validation, but it’s something to keep in mind. This can be partially resolved for Microsoft-specific styles by placing them in separate stylesheets using conditional comments, but other browsers’ opacity styles (specifically the opacity property) would still be in your main stylesheet, causing validation errors.

Update: I neglected to mention that you can get your stylesheet to validate if you set the validator options to use CSS3. You can even do this through the “referrer” link, like this (thanks to Steve for pointing this out):

The CSS opacity property is part of the CSS Color Module Level 3 (which is part of CSS3), and is (as of this writing) in the last call phase on the specification track, so although it is well supported, there is still some time before it is an official standard.

I hope I’ve covered the most important facts and code for cross-browser CSS opacity. If I’ve left out any important information, or made any errors, feel free to comment and I’ll gladly make any corrections or additions.

There’s a major difference between setting transparency via “opacity” and “background: rgb()”. Former sets opacity of the element and everything contained inside as well, including font (not so cool), whereas “background: rgb(r,g,b,alpha)” only sets the opacity of the element itself, leaving the children (including text inside) alone.

Unfortunately, since IE 6,7 and 8 are still clueless about CSS3, the only way to make a background transparent there is to use transparent PNGs and of course even with that you will have to show IE6 some special love.

And I’m glad you brought this up, because when validating a site by means of the “referrer” link that W3C gives you, it automatically defaults to CSS 2.1. To get it to use CSS3, you can add a querystring value, like this:

… which seems to suggest an anwser to your statement “To be honest, I really have no idea why you would even need either of the “progid” methods” – it seems you’d use these in order to get IE8-as-IE7 to work properly.

I’d be grateful if you’d give an opinion on this, cause I’m no expert and (like everything) it’d be great if the experts agreed!

Hi Louis. Nice article. But I’ve a question.
How to handle opacity and PNG both at same time on IE.
While trying to have a div with PNG (with transparency levels) background, I’ve used jQuery to animate opacity through $.fadeIn();
But you will see that breaks everything. Because jQuery detects if browser is IE, it uses filter. And PNG in IE6 you know it’s fixed by filter too.
The point you might be thinking right now is “but.. that’s just ie6, hell yah.” And my answer is NO!! I’ve discovered that in some weird way, microsoft team had deployed the fix (since IE7) for PNG using a kind of “filter” hidden property. So, if you set filter opacity to any element containing a PNG transparencies image as background, it will be broken even in IE8.

Good articles, but it must be possible to validate CSS with 3.0 with a link. There must be a way. I mean, it’s not that smooth to say this in the footer: “CSS – click here, and then change the settings so it validates with css3.0 and then press validate”… Anyone?

Leave a Reply

Comment Rules: Please use a real name or alias. Keywords are not allowed in the "name" field. If you use keywords, your comment will be deleted, or your name will be replaced with the alias from your email address. No foul language, please. Thank you for cooperating.

Instructions for code snippets: Wrap inline code in <code> tags; wrap blocks of code in <pre> and <code> tags. When you want your HTML to display on the page in a code snippet inside of <code> tags, make sure you use &lt; and &gt; instead of < and >, otherwise your code will be eaten by pink unicorns.