IE9, Opacity, and Alpha

IE9 introduces support for the CSS3 Color Module, including its popular opacity property. As we have done with other standards-based features, opacity is implemented so that the same markup used in other browsers just works in IE9’s ­standard mode.

Internet Explorer 8 and earlier versions implemented an alternative mechanism to apply opacity using the alpha filter of the IE-specific filter property. This creates a compatibility challenge because IE9’s standard mode supports only opacity and not the alpha filter. (IE9’s compatibility modes Quirks, 7, and 8 still support the alpha filter but do not implement opacity.)

For sites that use best practice feature detection, this is not a problem. They will detect that opacity is supported in IE9 and use it instead of filter. The problem is with sites that use browser detection and mistakenly assume that IE always uses filter alpha instead of opacity and then change only the filter property in script. The opacity effect will appear broken in those Web pages when run in IE9’s default 9 document mode. The fix is to detect the standards-based opacity feature first and browser-specific filter feature second as we’ve described in previous posts.

Example Best Practice CSS

 .fiftyPercentOpaque
{
    opacity: 0.5;
    filter: alpha(opacity=50);
} 
Example Best Practice Code
 // set flags for whether we should use opacity or filter with
// this browser (or browser mode). we prefer opacity.
var useOpacity =
   (typeof document.createElement("div").style.opacity != 'undefined');
var useFilter = !useOpacity
   && (typeof document.createElement("div").style.filter != 'undefined');

function setOpacity(el, value) {
   // let el be either an element object or an id string
   if (typeof el == 'string')
      el = document.getElementById(el);

   // ensure value is in [0-1] range
   value = Math.min(1, Math.max(value, 0));

   // set opacity or filter alpha depending on what's supported
   if (useOpacity)
      el.style.opacity = value;
   else if (useFilter)
      el.style.filter = "alpha(opacity=" + (value * 100) + ")";
}
Alternative Browser-detection Code

In general, we prefer feature detection to browser detection but we’ve see a lot of opacity-related code use browser detection instead of feature detection.  If you have a site that does that today, you may find it easier to update your browser detection so it works with IE9. Here’s code that properly detects when IE is running in a browser mode less than 9’s standards mode.

 function browserDetectSetOpacity(el, value) {
   // let el be either an element object or an id string
   if (typeof el == 'string')
      el = document.getElementById(el);

   // ensure value is in [0-1] range
   value = Math.min(1, Math.max(value, 0));

   if (navigator.userAgent.match(/\bMSIE\b/)
         && (!document.documentMode || document.documentMode < 9))
      el.style.filter = "alpha(opacity=" + (value * 100) + ")";
   else
      el.style.opacity = value;
}
Summary

The problem described above occurs only when the opacity of an element is changed using script that doesn’t detect whether opacity is supported before changing filter. Sites that use only declarative CSS markup will continue to work fine even when opacity is changed indirectly by changing the CSS class of an element or using a pseudo-class such as :hover.

W3Schools offers a clear explanation of CSS opacity and IE’s legacy alpha filter.

—Ted Johnson, Program Manager Lead for Web Graphics

Comments

  • Anonymous
    August 17, 2010
    Wow, charging ahead. That's great.   One question: The CSS example has the opacity setting before the filter setting. What is the IE9 algorithm that gives priority to the earlier setting? Does IE9 detect that opacity is specified and ignore later filter: alpha(opacity)  directives? What happens if the order is reversed? What if different filters are used? I would check this myself but don't have IE9 preview. Thanks, Sean

  • Anonymous
    August 17, 2010
    Sean, From the post "IE9’s standard mode supports only opacity and not the alpha filter." So it should just be ignored.

  • Anonymous
    August 17, 2010
    a off-topic question.. I am reading this post with IE8 @ XP SP3. When browser window's width is small, content in sample code block is overflow and horizontal scroll bar is displayed. But there is extra white space at the bottom of the sample code block. This happens in IE8 browser mode only, not in IE7 browser mode.

  • Anonymous
    August 17, 2010
    The comment has been removed

  • Anonymous
    August 17, 2010
    The comment has been removed

  • Anonymous
    August 17, 2010
    It's really unfortunate that IE9 can't use the same markup to display opacity that worked in IE8.  And that I have to write javascript to spit out CSS instead of, you know, just putting it in a .css file.

  • Anonymous
    August 17, 2010
    @c: the aim of this post is to deal with script-side property settings (when you want to modify element properties, say, in a fade-in/fade-out effect); if you want to do it the 'static CSS way', then it's much simpler:

  • you put your standard code in a CSS sheet that all browser load (and Firefox, Safari, Opera, Chrome and IE 9 will use just that)
  • you put IE fixes (such as 'filter') in a spare sheet that you load through conditional comments (and IE 5/6/7/8 will apply these over/on top of what they could understand from the above CSS sheet) Well, dealing with IE 5/6 may be overkill... But it can be done!
  • Anonymous
    August 17, 2010
    @c The article gives an example of, "you know, just putting it in a .css file"

  • Anonymous
    August 17, 2010
    When you say you're supporting the Color module, does that include HSL values too?

  • Anonymous
    August 17, 2010
    Peter Gasston, msdn.microsoft.com/.../ff468705.aspx

  • Anonymous
    August 17, 2010
    Here is the same code revised for readability and normal coding standards: CSS: .fiftyPercentOpaque{    opacity:0.5;    filter:alpha(opacity=50); } Code 1: /* set flags for whether we should use opacity or filter with this browser (or browser mode). we prefer opacity. */ var useOpacity = (typeof document.createElement('div').style.opacity != 'undefined'); var useFilter = !useOpacity && (typeof document.createElement('div').style.filter != 'undefined'); function setOpacity(el, value){   // let el be either an element object or an id string   if(typeof el == 'string'){      el = document.getElementById(el);   }   // ensure value is in [0-1] range   value = Math.min(1, Math.max(value, 0));   // set opacity or filter alpha depending on what's supported   if(useOpacity){      el.style.opacity = value;   } else if(useFilter){      el.style.filter = 'alpha(opacity=' + (value * 100) + ')';   } } Code 2: function browserDetectSetOpacity(el, value){   // let el be either an element object or an id string   if(typeof el == 'string'){      el = document.getElementById(el);   }   // ensure value is in [0-1] range   value = Math.min(1, Math.max(value, 0));   if(navigator.userAgent.match(/bMSIEb/) && (!document.documentMode || document.documentMode < 9)){      el.style.filter = 'alpha(opacity=' + (value * 100) + ')';   } else {      el.style.opacity = value;   } } Although I wouldn't recommend the 2nd code snippet as it goes against coding principals - your method should only do one thing, and be labeled as such. The real question is - is this a full proper opacity implementation or a wrapper on the filter:alpha code? because we all know that filter:alpha has some bugs still.

  • Anonymous
    August 17, 2010
    ...still, it's all well and good, but I wonder WHEN, with the new Jscript engine AND the new DOM support, will setAttribute be properly supported. And yes, the DOM is entirely loaded. Whether I do document.getElementById('test').type = 'hidden' or document.getElementById('test').setAttribute('type','hidden') I get 'command not supported' - whether it's in IE 8 proper, IE8 mode or IE 9 in IE9pre4. All other browsers do it properly without a problem. Please IE team, could you at LEAST fix the DOM support in IE 9?

  • Anonymous
    August 17, 2010
    @revised - that may be normal coding standards (I'm not sure what normal coding standards for CSS are), but I disagree that removing whitespace aids to the readability of that CSS sample...

  • Anonymous
    August 17, 2010
    The comment has been removed

  • Anonymous
    August 17, 2010
    Great stuff, nice job IE team. Keep up the blog. A statement on WebGL (either way) would be very welcome, as per someone above.

  • Anonymous
    August 17, 2010
    You're right - I completely missed the .css example.  Which was the first thing on the stupid page.  My bad.

  • Anonymous
    August 17, 2010
    The comment has been removed

  • Anonymous
    August 17, 2010
    The comment has been removed

  • Anonymous
    August 18, 2010
    <<I'm sure some heads at Microsoft would love if you stop with this openness and standards direction>> Yeah, I'm sure the IE team is coding away at night, sneaking in to use the Microsoft facilities despite the objections of the top management they all work for. They're secretly embracing standards and they have collected dirt on their bosses so that they cannot be fired despite failing to follow orders. You have an amusingly naive view of the world.

  • Anonymous
    August 18, 2010
    This is a first for me, but nice job Team IE. Getting rid of the non-standard stuff is the best way to make sure it doesn't continue to propagate in the wild. Yes, in some cases it will require updates to long-stable code, but it's for the best. Nice to know that even my older sites that used conditional comments to implement IE specific CSS will continue to function in IE9 since it will obey the original opacity rule and disregard the alpha filter in the IE8+ stylesheet.

  • Anonymous
    August 18, 2010
    @Cowboy - I think the best practice for most people is to use a library to abstract away the need for feature detection. Then all you'd need is something like - "el.fadeTo(100, .5)" - and you're done.

  • Anonymous
    August 18, 2010
    @Silly,  so you're telling me that EVERYONE at Microsoft sees eye to eye with Google here on the importance of the web as an OPEN platform? You are telling me that all the managers at Microsoft think that? Pushing open standards over closed ones? Remainder: Google makes money from advertising, while Microsoft from selling licenses. Google, IMO, understand the value of open-source (think Wikipedia vs Encatra RIP), while Microsoft makes money from software. Yes, I naively believe Google is for openness, and even though MS yells all day "yes we're open, DOTNET is open, etc." I don't believe them for a sec. IETeam excluded :-).

  • Anonymous
    August 18, 2010
    The comment has been removed

  • Anonymous
    August 18, 2010
    Is there a way to disable this fade in and fade out effect in IE?

  • Anonymous
    August 18, 2010
    The comment has been removed

  • Anonymous
    August 18, 2010
    @Anonymous: ever since Vista's release, OpenGL has been made available in Windows as an OpenGL-to-DirectX9 translation layer. Your objection is valid WRT Windows XP, but it doesn't hold water for Vista/7.

  • Anonymous
    August 18, 2010
    Will rgba color declarations be supported in IE9?

  • Anonymous
    August 19, 2010
    @mitch074 This article contradicts your claim www.dailytech.com/article.aspx

  • Anonymous
    August 19, 2010
    The article seems to state that an OGL to Direct3D wrapper exists in Vista already, but that Khronos have made available drivers to allow OGL to run natively. Assuming that's true, the article doesn't contract mitch. If not, IE could still implement some kind of wrapper for the GL functions that are contained within the GL spec that would translate it to Direct3D. Google are working on something that will do that.

  • Anonymous
    August 19, 2010
    If the W3C creates a 3D version of Canvas or SVG it could be supported by either OpenGL or Direct3D.

  • Anonymous
    August 19, 2010
    I use conditional comments for IE specific stuff however I also now (Version 2.9+) use object detection with the DOM to determine the browser's rendering engine and version and load a CSS3 style sheet specific to that browser. This allows me to load all the properties, selectors, etc that are CSS3 based for each browser without triggering errors and/or warnings. It's a bit more JavaScript code then that is posted (I cover IE 5.5+, Gecko 1.0+, Opera 7.0+, and Safari 2.0+) however the coverage for CSS3 it provides is everything one could need. ...so knowing this why are you guys looking at the user agent string in your example code? Seriously, you guys should email me before you post JavaScript on the blog.

  • Anonymous
    August 19, 2010
    jabber: You should probably work on Reading Comprehension. They explicity state why they offer a version that uses User-Agent detection. And no, I don't think you get the benefit of the doubt just because you're the author of Version 2.9 of "Unusably ugly site."

  • Anonymous
    August 19, 2010
    Must be sad living under a bridge refreshing the IE blog once every 30 seconds just to troll someone only to never get an emotional response. =^.^=

  • Anonymous
    August 19, 2010
    The comment has been removed

  • Anonymous
    August 19, 2010
    @Neal Yes. See msdn.microsoft.com/.../ff468705.aspx .

  • Anonymous
    August 19, 2010
    Maybe I'm missing something here but shouldn't the best practice for the CSS opacity declaration be: .fiftyPercentOpaque{    opacity:0.5; /* Modern Browser support (including IE9) /    -ms-filter:"alpha(opacity=50)"; / IE8 support /    filter:alpha(opacity=50); / IE fallback support for IE7, IE6, IE5.5, IE5... */ } Or have you guys already forgotten about IE8? blogs.msdn.com/.../the-css-corner-using-filters-in-ie8.aspx @mitch074 - Precisely! fixing the existing DOM bugs should be of highest priority.

  • Anonymous
    August 19, 2010
    The comment has been removed

  • Anonymous
    August 19, 2010
    (Comments on "HTML5, Modernized..." seem to be closed, so I'm posting here.) I urge IE Team to consider supporting the "text-shadow" CSS property in IE9, while there is still time left for that. "text-shadow" has been supported since Safari 1.1 (October 2003), Opera 9.5 (June 2008), Chrome 2.0 (May 2009), Firefox 3.5 (June 2009) [see www.kremalicious.com/.../make-cool-and-clever-text-effects-with-css-text-shadow]. By now, it has become pretty wide-spread. A lot of real websites and blog themes use it, mostly for engraved/embossed-style text [also: www.w3.org/.../text-shadow]. I'd argue that "text-shadow" is probably the single most used CSS3 feature not yet supported by IE9. CSS 2D Transforms? Still exotic. Multiple columns? Even more rare. On the contrary, text shadows are already being used on lots of real sites. So, in keeping with the IE9 philosophy of "same markup everywhere", "text-shadow" really belongs in IE9 as a feature. Plus, once you implement it, it will work right away on all existing sites, since it has no vendor prefix. Now, just as you are retiring "alpha" filter while simultaneously introducing "opacity", you can do the same for "dropshadow", "shadow" and "glow" filters. Here are a few examples:

  1. filter: dropshadow(offx=5,offy=3,color=red); => text-shadow: 5px 3px red;
  2. filter: shadow(color=red,direction=45,strength=5);    [looks like fade-out extrusion] => text-shadow: 1px -1px rgb(255,  42,  42),                             2px -2px rgb(255,  85,  85),                             3px -3px rgb(255, 127, 127),                             4px -4px rgb(255, 170, 170),                             5px -5px rgb(255, 212, 212);
  3. filter: glow(color=red,strength=5); => text-shadow: 0 0 8px red,                             0 0 8px red,                             0 0 8px red,                             0 0 8px red; To sum up, the main motivation is to be able to use blurred drop shadows (which is currently impossible using filters), and to support existing and widely-used CSS property that currently works in all browsers except IE.
  • Anonymous
    August 19, 2010
    @mitch074 -- Please add it to the bug tracker, so we can vote up.

  • Anonymous
    August 19, 2010
    @jabcreations That wasn't a troll, just the truth. You need to learn how to read.

  • Anonymous
    August 20, 2010
    The comment has been removed

  • Anonymous
    August 21, 2010
    @Sergei I'm pretty confident the final build will include text-shadow. (You can laugh at me when time proves me wrong.) Microsoft has this new mantra: underpromise, overdeliver. They will not let this one slide, especially so because it is such an exposed feature for the end-user. They're just aiming for the buzz and excitement it will generate among the developers. (Remember canvas?) I expect the IE-team to tie up a lot of loose ends before the beta.

  • Anonymous
    August 21, 2010
    @Nick -- Yes, the markup you propose using the -ms-filter property does indeed work in IE8 but it's not needed. During the IE8 endgame, a change was made to also support the legacy filter property (without the -ms- prefix) to improve compatibility with existing sites. I chose to show the minimum markup that's required.

  • Anonymous
    August 21, 2010
    The comment has been removed

  • Anonymous
    August 21, 2010
    The comment has been removed

  • Anonymous
    August 21, 2010
    The comment has been removed

  • Anonymous
    August 22, 2010
    Just a reminder: innerHTML is still broken in IE9 platform preview 4.

  • Anonymous
    August 22, 2010
    Please Microsoft this time I want a better Internet Explorer. A faster, lightweight, secure IE9 than all the other browsers.

  • Anonymous
    August 22, 2010
    The comment has been removed

  • Anonymous
    August 23, 2010
    @still not fixed: you should not use innerHTML. Period. Use DOM methods (or libraries that do), that'll spare you some headaches. It did for me.

  • Anonymous
    August 23, 2010
    The comment has been removed

  • Anonymous
    August 23, 2010
    @realistic "if you are creating a bunch of content all at once innerHTML outperforms any other DOM method hands down" The HTML elements that IE does not support with InnerHTML do not come in bunches generally.

  • Anonymous
    August 23, 2010
    @realistic "when the bug has been known since at least 2000" A bug against what spec?

  • Anonymous
    August 24, 2010
    The comment has been removed

  • Anonymous
    August 24, 2010
    @realistic: while innerHTML used to be much faster than DOM methods (more specifically, it was 300x faster in IE 6; in other browsers, the ratio was MUCH lower - and we're talking 2007 browsers, before the speed rush to DOM and JS optimizations), it's no longer so true  - and on the other hand, innerHTML is risky, supported unevenly across browsers, and a kludge. I know that doing away with innerHTML and replacing it with DOM methods (and I don't use jQuery: I do my code myself, not to say jQuery is bad - I just enjoy tinkering) didn't make my pages slower, and solved a bunch of Schroedinbugs in all browsers. Which is a win in my book.

  • Anonymous
    August 25, 2010
    @realistic Don't forget that IE9 PP4 is now one of the top 2 browsers - Chrome and IE9 - in ECMAScript performance, so you may want to revisit using DOM operations. Benchmark here: ieblog.members.winisp.net/.../Dean_PPB4_6.png (Opera is slightly faster than both, but is not a major browser in terms of marketshare)

  • Anonymous
    August 26, 2010
    Opera is really not important. But the same goes for IE9. Firefox rocks.

  • Anonymous
    August 26, 2010
    @Ted Johnson [MSFT] You said " Example Best Practice CSS .fiftyPercentOpaque {    opacity: 0.5;    filter: alpha(opacity=50); } " and later added " the markup you propose using the -ms-filter property does indeed work in IE8 but it's not needed. During the IE8 endgame, a change was made to also support the legacy filter property (without the -ms- prefix) to improve compatibility with existing sites. " but Sylvain Galineau [MSFT] said on 20 Feb 2009 " The -ms prefix in your static style rules is something _ we recommend _ not just to be a good standard citizen but because it is the forward-looking thing to do in your future stylesheets. " You provided the code [   else if (useFilter)      el.style.filter = "alpha(opacity=" + (value * 100) + ")"; ] but that is not how MSDN ( ms532847 ) recommended and recommends to do this. There are blatant contradictions here ... or again nobody ever udpates anything (content, code, example, markup validity, schemas, interactive examples, etc.) at MSDN and no one ever bothers about recommendation coherence, code consequence, etc. Gérard Talbot

  • Anonymous
    August 26, 2010
    @Ted Johnson [MSFT] function browserDetectSetOpacity(el, value) {   // let el be either an element object or an id string   if (typeof el == 'string')      el = document.getElementById(el); Personally, I would never name a string variable which is supposed to hold an id attribute value like you did. This reusing of the el identifier creates a confusion in the minds of beginners; it's a poor (and misleading) choice of identifier too. I would have chosen strIdAttribute (prefixing the returned value type) or something like that. " W3Schools offers a clear explanation of CSS opacity and IE’s legacy alpha filter. " Does such statement officially announces that MSDN will soon become some sort of documentation graveyard or archives not worth upgrading nor updating and that, from now on, people should go/will have to go to W3Schools to get clear explanation, good examples written with valid markup code and valid CSS code? Gérard Talbot

  • Anonymous
    August 29, 2010
    The Opacty filter has some mayor bugs in IE8 with PNG files. Why can't this be fixed in IE8? This will not affect any excisting website. It is just a bugfix. I am assuming that it will be fixed in IE9.

  • Anonymous
    August 29, 2010
    The comment has been removed