Friday, April 08, 2005

IE6 opacity filter caveat

This one was a real pain. I was lucky to guess the solution.

I was working on a very small function to set alpha transparency on elements. This is what I came up with:


var ie = (document.all) ? 1 : 0;
var p = (ie) ? "filter" : "MozOpacity";

/* n is the element node
   v is the opacity value, from 0 to 100. */

function op(n,v){
    v = (ie) ? "alpha(opacity="+v+")" : v/100;
    n.style[p] = v;
}

(Yes, I know I left Opera and Safari/KHTML out of the equation.)

This function worked great in Firefox but nothing was happening in IE6. I tried a bunch of different tweaks, none of which worked. Adding an alert(n.style.filter); at the tail end of the function returned "alpha(opacity=50)" indicating that the value was being set correctly for IE6. But the element still rendered at 100% opacity.

Finally, I threw the function out altogether and applied the filter directly to the DIV element via CSS:

<div id="myDiv" style="filter:alpha(opacity=50);">
<img src="MyImage.gif" alt="Some Image Here" 
  width="50" height="50" />
<br />
This should be transparent.
</div>

But it still didn't work! IE6 stubbornly ignored the opacity rule. Even more confusing was that moving the opacity rule to the image alone did work. But only on the image, of course.

<div id="myDiv">
<img style="filter:alpha(opacity=50);" src="MyImage.gif" 
  alt="Some Image Here" width="50" height="50" />
<br />
This should be transparent.
</div>

I really needed the opacity applied to both the text and image. I was about to give up when it occurred to me that maybe the image width and height dimensions has something to do with it. By default, a block element takes on the width of its containing element and height of its content, but maybe IE6 was ignoring this when applying the alpha filter. So I tried this:

<div id="myDiv" 
  style="filter:alpha(opacity=50);
     width:100%; height:100%;">
<img src="MyImage.gif" alt="Some Image Here" 
  width="50" height="50" />
<br />
This should be transparent.
</div>

Yes! Opacity was now being applied to both the image and the text. I removed opacity rule from the DIV and was then able to correctly set opacity via the JavaScript function.

I don't have the luxury of testing this across the different flavors of IE, but it appears that alpha opacity in IE6 requires certain elements to have a specified width and height. What's funny is that when I tried Googling for answers to my problem, I found a ton of working examples that used opacity in IE6 successfully. Looking back now, all of those examples specified a CSS width and height on the element, but didn't make any specific mention of it as a requirement for IE. Removing the width and height caused those examples to fail, too.

UPDATE: Dean Edwards points us to the MSDN documentation for this little-known behavior. IE filters only apply to elements with "layout."

34 Comments:

At 12:28 PM, Anonymous Mark Wubben said...

Odd. Did you know that in IE 5.0, you can't retrieve the opacity via `currentStyle`? You need to use `style`. Also, if you fade an element (in IE 5.5 or 6, I'm not sure anymore, it's been a while) and you have an iframe in that page, the scrollbars of that iframe will flicker.

 
At 12:38 PM, Anonymous Dean Edwards said...

Filters only apply to elements with "layout":

http://msdn.microsoft.com/workshop/author/dhtml/reference/properties/haslayout.asp

An obscure Microsoft concept to differentiate between it's different rendering models. Annoying isn't it?

 
At 1:27 PM, Anonymous Nick O'Neill said...

Yeah, this bug is a pain. Applying width and height is the *last* thing you think of doing when opacity isn't working.

I was working on some fading stuff a few weeks ago and I was running in to strange issues when opacity gets below .08 - check out this demo*. It pulls opacity from style.MozOpacity, reduces it and then applies it back to all opacity settings. The values I'm spitting out are the values of a variable I used to set opacity and style.MozOpacity. MozOpacity keeps getting set to a value below .08 even though the variable I use to set it is returning undefined below .08. I got around it for my fading stuff but I can't seem to figure out what I'm doing wrong.

*IE doesn't like setting style.MozOpacity ever so this probably won't work. Same results in safari and firefox though.

 
At 9:46 PM, Anonymous timb said...

I know you know you left Safari out, but, you should use style.opacity rather than style.MozOpacity. It's the standard css3 property, and works in both Mozilla and Safari.

 
At 11:54 PM, Blogger scottandrew said...

Thanks Tim, I didn't know Moz supported "opacity" (does that mean we can ditch "KhtmlOpacity" too?)

 
At 8:23 AM, Anonymous Richard@Home said...

Yup, I got bitten by this one too.

Check out my article: CSS Transparency for Internet Explorer (IE), Mozilla and Safari Redux

I *think* you can just get away with specifying the width. It seems to work for me in my examples.

 
At 3:11 AM, Blogger Martijn said...

Scott, you still have an error in your saveCookie function. It's biting me every time I borrow that code.
var d = new Date();
d.setTime(d.getTime()+(days*24*60*60*1000));
var ex = "; expires="+date.toGMTString();

Error: date is not defined

 
At 12:32 PM, Anonymous Ben Karel said...

Out of curiosity, why don't you use more descriptive (e.g. self-documenting) variable names?

var is_ie = typeof(document.all) != 'undefined';
var opacity = (is_ie) ? "filter" : "opacity";

function changeOpacity(node, percent){
percent = (is_ie) ? "alpha(opacity=" + percent + ")" : percent/100;
node.style[opacity] = percent;
}


... requires no explanatory comments, see? (Though it's rather clearer when the lines aren't forced to wrap like that...)

 
At 11:47 AM, Blogger scottandrew said...

Ben: because a lot of my work requires delivering the desired functionality in as little code as possible. This JS usually ends up being compressed, making it even more obscure.

That's why :)

 
At 8:41 PM, Blogger John said...

Mmm, nice. I was just doing a fade out that works for IE and left the job of fixing it to work in Firefox to tomorrow. You just saved me some effort. Thanks!

 
At 11:02 AM, Blogger funny said...

this is a really cool-e-o web!ttyl

 
At 11:02 AM, Blogger funny said...

this is a really cool-e-o web!ttyl

 
At 4:20 AM, Blogger Faisal ... said...

Thanks for the tip it really worked.

 
At 2:54 PM, Blogger Silviu Lucian Văcăroiu said...

grate stuff ... it's 00:52 in the AM and IE was driving me nuts ... :) ... I came across your article by mistake (I was searching for something else) ... again many thanks

 
At 2:55 PM, Blogger Silviu Lucian Văcăroiu said...

works fabu', now I can go to sleep, yeeey :D

 
At 8:00 PM, Blogger Freddies Blog said...

Last month I made $12,124 with Google Adsense... Click
here for free information on how you can do the same!

 
At 6:11 AM, Blogger Mizambar 6294 said...

Last month, I earned $12,124 from Google Adsense, click here for free information to find out how you can do the same

 
At 1:55 PM, Blogger Freddies Blog said...

Last month, I earned $12,124 from Google Adsense, click here for free information to find out how you can do the same

 
At 10:23 PM, Blogger Bullfrog said...

Hi, I am trying to ge the Myspace (www.myspace.com blog like site) to have 10% opacity background in the tables if any one knows how to do this with IE tell me. I have it for firefox

zreodark@hotmail.com

Here is an example:

www.myspace.com/socalhazzard
look at it though firefox them IE
thanks

 
At 7:19 AM, Blogger HiiFii Webservices said...

I wanted to show you some superb resourses on the net.
Learn to earn 90000$/Month
For which you may also see my Personal Website
Here.
and for a Personal Education Career Tools
free Study Database.
This site is for seeing the
Hifi Electronics.
And this is for
World Class Gadgets

 
At 2:22 PM, Blogger Princess Sarah said...

whenever i try to apply opacity to a div containing text, the text becomes very visibly distorted. any suggestions?!

 
At 7:36 AM, Blogger duke said...

The cost of oil has reached an all time high. Our politicians need to be more aggressive in combating these increases.
Airline Tickets

 
At 7:38 AM, Blogger duke said...

Bingo
Camping
Coins
Banking Guide
Speeding Tikcet
Alaska Fishing
Bankruptcy
Business Logos
California Wines
Treadmill Exercise
Plastic Surgery
Digital Cameras
Vending
Machines

smoking system
Student Cards
Loan Solutions
Walking Tours
White Water Rafting
Bird Bath
Broad Band
Celtic Jewelry
Changing Table
Cheap Flowers
Chess Set
Crystal Chandelier
Disney Ticket
Down Comforters
Fire Safe
Foam Mattress
Forex Trading
Hamster Cages
Hawaiian Shirt
las vegas deals
lift chair
NFL Jerseys
Best Hosting
Portable Generator
Credit Repair
Event Planning
Gardening
Hydroponic
Systems

Investing
Used Cars
Patio Umbrella
Resumes and
Interviews

Softball Bat
Cell Phone
Golf Vacations
Insomnia Cure
Wall Fountain
Discount Tickets
Wireless Speakers
Airline Tickets
Dogs
Antiques
Augmentation
Earn Money At Home
Baby Names
Bariatric Treatment
Wireless Speakers

 
At 10:01 AM, Blogger vissu said...

I was going through the exact same thing and your trick of defining width/height made it to work. thanks so much for posting!

 
At 12:03 AM, Blogger kingsonone said...

GOD HOW I HATE FEEBLE PEASANTS WHO SPAM :)

This is an excellent article , thank you.
Though I dont write with Safari in mind I've picked up on the "style.opacity" and the "layout" tips and shall be using them.

 
At 9:49 AM, Blogger Dunk said...

Wonderful mate! If only it had come before I had managed to pull all my hair out....IE, you've got to love it. NOT!

 
At 8:56 PM, Blogger Ian Yang said...

this is really a life saver! i'm working on my website right now and just can't figure out what has gone wrong with this opacity thing. The odd thing is after I put something like:

filter:alpha(opacity=30);
opacity:0.3;

in my style sheet, both FF and IE6 display the effect I want without any further issue. Thanks a lot for this great post! :D

 
At 9:00 PM, Blogger Ben said...

Rather than using width:100%;height:100%
just try position:relative;

;-)

 
At 6:03 PM, Blogger satxxkenn said...

Cool blog - Check out my site if you need help finding a good low interest credit card. Credit Cards

 
At 3:00 PM, Blogger Goran said...

I'm trying to have transparent text in IE6 but doesn't work with width:100% and height:100% and also doesn't work with position:relative

 
At 9:49 PM, Blogger meusfilia said...

No biggie but there's a tag missing after the div id=myDiv.

 
At 8:28 AM, Blogger Bovine Spongiform Encephalopathy said...

I would just like to say that your blog post has saved me from an hour or so of banging my head against the wall.

It was driving me mental why I simply could not apply opacity to a blockquote element in IE6.

Took your advice and gave it a non percentage based height (percentage didn't work) and hey presto it works.

 
At 8:43 PM, OpenID hankin said...

I checked my web logs the other day, IE6 is still pretty popular.

Setting any of these will give your element a layout...

http://msdn.microsoft.com/en-us/library/ms533776(VS.85).aspx

display: inline-block
height: any value
float: left or right
position: absolute
width: any value
-ms-writing-mode: tb-rl
zoom: any value

 
At 11:28 AM, Blogger Kevin X Brown said...

Thank you very much for the post - very helpful in resolving a problem I have just encountered with applying a gradient filter in IE8, which had the same issue.

 

Post a Comment

<< Home