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