Opacity problem css 2.1

Below is a basic img opacity change I’ve applied to my img links, but W3C says it’s not valid only in css 3.0, so my question; how do I get this to work in css 2.1

#galleryholder a img  {
		border:1px dashed #444;
		margin: 0 14px 0 0;

#galleryholder a:hover img  {
		border:1px dashed #F4F4F4;


Parse Error opacity=80)
#galleryholder a img Parse Error opacity=80)
#galleryholder a img Property -moz-opacity doesn’t exist : 0.8
#galleryholder a img Property opacity doesn’t exist in CSS level 2.1 but exists in [css3] : 0.8
#galleryholder a:hover img Parse Error opacity=100)
#galleryholder a:hover img Property -moz-opacity doesn’t exist : 100
#galleryholder a:hover img Property opacity doesn’t exist in CSS level 2.1 but exists in [css3] : 100

Any suggestions? Thanks :cool:

You can move the filter property to IE stylesheets, but honestly you should NOT worry about the opacity error AT ALL - if you’re using CSS 3 properties then it wouldn’t make sense at all to validate for 2.1 because CSS3 properties weren’t available at the time. This is similar to trying to validate HTML 2.0 when using HTML 4.01 Strict syntax, cater to the highest denominator ( validation-wise ) basically.

SoulScratch is correct; the main problem is that opacity is one of the most problematic things to implement through CSS. There is no real way you can implement opacity within CSS 2.1 as Opacity itself was only introduced in the CSS 3 specification, and what makes it worse is that for this to work in IE and other older browsers, you require a mixture of anything up to 5 different custom declarations. IE8 uses a different declaration to IE7, old versions of Mozilla and Konquerer use different declarations of their own and of course there is the CSS 3 element.

Do not be ashamed to use CSS 3 in your website, it shows you are keeping up with the times. And for the record, don’t rely on the W3C validator. Yes, it is good to have valid semantic code, however the time of having to use hacks and browser specific code is not over and if you are using them for a valid reason (such as opacity), there is no shame in using them to accomplish the required task.

Note that IE8 doesn’t support any of the above and you would need to use this proprietary IE code.

.opacity {
    -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=50)";

As mentioned above the IE code can go in conditional comments and then validate the rest against css3 (it’s in the advanced options). The -moz-opacity won’t validate though but is only needed for older gecko and could be dropped anyway.

Thanks a lot guys, it’s always a lot better to hear this from some other experienced coders, I’ve always stuck to the W3C standards and always modified my code to run correctly, either by applying certain comments or hacks but like you say

you should NOT worry about the opacity error AT ALL
I just thought there might be a simply way around this.

It’s always nice though knowing that you code is validated correctly.

So if I understand; apply some IE comments to cater for IE and remove moz-opacity and your good to go.

And thanks for the big explanations guys :slight_smile:

Well, using just ‘opacity’ will still throw a warning/error, the main suggestion is to change the Profile Level on http://jigsaw.w3.org/css-validator/#validate_by_uri+with_options to use ‘CSS Level 3’.

Could use the short hand version too. -ms-filter: "alpha(opacity=50)"; I tried it in IE 8 RC and seems to have worked.

I see, thanks SoulScratch! :slight_smile:

Yes thanks logic, -ms-filter: "Alpha(Opacity=50) seems ok, I did try my previous code without the IE 8 code above and seems to still work without applying the extra code, or am I missing something?

I did use the NetRenderer which is just a screen shot of IE8 RC but my images seem faded.


If I remember correctly, to get opacity to work in earlier versions of IE (including IE6), you may need to apply the long handed version as it requires rendering through the DirectX engine as opposed to the built in proprietary filter.

Edit: Yes apparently I was right, though it will enable transparency in IE5x and IE for mac (which we dont really need to support anymore).

OK, here is the full compatability list for achieving opacity for the widest range of browsers…

.opacity {
-moz-opacity: 0.5;
-khtml-opacity: 0.5;
-ms-filter: "alpha(opacity=50)";
filter: alpha(opacity=50);
filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=50)";

opacity:.50; = this is the CSS3 default, modern browsers should work with it.
-moz-opacity: 0.5; = this is for Netscape and old Mozilla browsers.
-khtml-opacity: 0.5; = this is for v1 of Safari and old Konquerer versions.
-ms-filter: “alpha(opacity=50)”; = this is for Internet Explorer v8.
filter: alpha(opacity=50); = this is for Internet Explorer v6 and v7.
filter: “progid:DXImageTransform.Microsoft.Alpha(Opacity=50)”; = this is for Internet Explorer v5.x and IEMac.

Now I bet you wish you used transparent png files.

For IE6 he would still need a fix for that so transparent png files wouldn’t be much less work.

Correct, but then you only have to workaround one browser, not many.

Yea but getting IE6 to work is more manual labor then just typing in a few lines of code, which aren’t really all that long. IE6’s fix (twinhelix at least) takes up a good 30 lines of code somewhere. 30>6.

I would agree, supporting transparent PNG’s are currently the more obtrusive of the two options (CSS requires less code to accomplish the task of opacity), when IE6 is removed from the mix however, then we can use PNG’s with alpha transparency naturally and avoid the use of requiring the many different CSS declarations.

It kinda sucks IE6 doesn’t have alpha transparency channel support. If only…

Anyway I won’t pretend to brag here that I have the fix for IE6 png problem memorized: heck I can’t even tell you how it works. I just download the files, upload it and put the lines of code that I need into my program.


In IE8 beta2 most of the filter versions worked but IE8 RC1 seems a bit more strict however some versions of the old filters are still working.

However, I guess we have to assume that support may be dropped completely due to the fact that the old filters don’t follow the correct rules for vendor specific extensions and we should only rely on the -ms-filter working in IE8.

I put up a test page for IE only (if anyone is interested) and there are some strange results.

Test Page
Browsercam results

Although MS have advised authors to use this property along with their vendor prefix, it actually doesn’t work in the current RC1. Test Case. I am unsure as of yet whether this issue will be corrected before final release.

You can also use the shorthand ‘filter’ value syntax, ‘alpha(opacity=40)’ which will also work

Hi James,

You missed my follow up post which explains the issue in detail in my test page (which seems to be down at the moment) that I linked to in post #16. :slight_smile:

You are incorrect and if you look at my test case then it does work in RC1. You forgot to include the quotes and it works fine. Both the longhand and shorthand versions of the -ms filter work as long as you you “quote” the properties correctly.

There are some important exceptions and things are not as straight forward as you may think.

Here is the test page code reproduced.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
<style type="text/css">
p {
    margin:0 0 .5em
.opacity {
.a1 {
.a2 {
.a3 {
    filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=40)"
.a4 {
filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=40)
.a5 {
    -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=40)";
.a6 {
-ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=40);
.a7 {
    -ms-filter: "Alpha(Opacity=40)";
.a8 {
    -ms-filter: Alpha(Opacity=40);
.a9 {
    -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=40)";
<h1> IE5.5 - 8 opacity test </h1>
<h2>Note that IE6 and IE7 need haslayout applied to the element for opacity to work</h2>
<h3>IE8 RC1 doesn't apply opacity to elements with display:inline</h3>
<div class="opacity a1">
    <p>opacity1 ... filter:"Alpha(Opacity=40)" (with quotes) </p>
    <p>Works in IE5.5 only</p>
<div class="opacity a2">
    <p>opacity2 ... filter:Alpha(Opacity=40) (no quotes)</p>
    <p>Works in IE5.5, IE6, IE7 and IE8 RC1</p>
<div class="opacity a3">
    <p>opacity3 ... filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=40)" (with quotes)</p>
    <p>Works in IE5.5 only</p>
<div class="opacity a4">
    <p>opacity4 ... filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=40) (no quotes)</p>
    <p>Works in IE5.5, IE6, IE7 and IE8 RC1</p>
<div class="opacity a5">
    <p>opacity5 ... -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=40)" (with quotes)</p>
    <p>Works in IE8 RC1 only</p>
<div class="opacity a6">
    <p>opacity6 ... -ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=40) (no quotes)</p>
    <p>Works in none</p>
<div class="opacity a7">
    <p>opacity7 ... -ms-filter: "Alpha(Opacity=40)" (with quotes) </p>
    <p>Works in IE8 RC1 only</p>
<div class="opacity a8">
    <p>opacity8 ... -ms-filter: Alpha(Opacity=40) (no quotes)</p>
    <p>Works in none</p>
<div class="opacity a9">
    <p>display-inline ... filter:Alpha(Opacity=40);<br />
        -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=40)";</p>
    <p>Doesn't work in IE8 but will work in ie5.5 - 7 (because element haslayout via zoom property)</p>
<p>Ie8 RC1's behaviour has changed since IE8 beta2 when it would have worked with all 4 of the below.</p>
<p>#opacity1 {<br />
    background:red;<br />
    filter:&quot;Alpha(opacity=60)&quot;;<br />
    margin:10px;<br />
    }<br />
    #opacity2 {<br />
    background:red;<br />
    -ms-filter: &quot;progid:DXImageTransform.Microsoft.Alpha(Opacity=50)&quot;;<br />
    margin:10px;<br />
    }<br />
    #opacity3 {<br />
    background:red;<br />
    -ms-filter: &quot;Alpha(Opacity=40)&quot;;<br />
    margin:10px;<br />
    }<br />
    #opacity4 {<br />
    background:red;<br />
    filter: &quot;progid:DXImageTransform.Microsoft.Alpha(Opacity=20)&quot;;<br />
    margin:10px;<br />
<p>I think we should assume that the only safe styles for future versions of IE8 would be to use the following combinations.</p>
<p> filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=40)<br />
    -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=40)" </p>
<p>Or:<br />
    filter:Alpha(Opacity=40);<br />
    -ms-filter: "Alpha(Opacity=40)"; </p>

The point being that quotes around the properties are important (they need to be in place for some versions and need to missing for others). You can see this in the browsercam results.

Hope that helps others as you can view the browsercam results to see what works where.

This would be the best combination to use which works in IE5.5- ie8.

 -ms-filter: "Alpha(Opacity=40)";

Or the longhand version as follows:

 filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=40)
  -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=40)"