Tuesday, June 26, 2012

CSS Opacity, IE Filter, Binary and Script Behaviors

(This article is about using IE specific "filter" to mimic the standard CSS attribute "opacity", this mimicry's consequence when the Binary and Script Behaviors setting is disabled in IE8 and IE7, and the workaround.)

CSS is not rocket science, but nonetheless difficult due to the infamous browser-compatibility issue. Any experienced web developer will tell you that CSS is a mess. The CSS standard doesn't look very complicate on paper, however, in reality, there are always some corner cases that break your UI in certain browsers (most likely IE). Some of such corner cases are well documented and mind-shared in the web developer community, however, some of them are not so well known, lurking there to ambush you.

I got ambushed today by such corner case. This corner case is so nasty that it cannot be reproduced in most browser settings. Here is the story:

Opacity is a standard CSS attribute invented to control transparency of HTML elements. However, not so surprisingly, IE under version 9 doesn't support "opacity". To fix that, most articles returned by Google search will recommend adding "filter" -- a IE specific attribute to mimic "opacity".

#trans {
  opacity: 0.4;
  filter: alpha(opacity=40); /* For IE8 and earlier */

Snippet 1

The above snippet I partially copied from w3schools.com (link) works in most browser settings. Actually, it works so well that most web developers won't have to worry about it in their lifetime.

My application is a third-party web app. It works in a tight security environment in which IT built up a fortress to fend off any possibly suspicious activity. One of such suspicious activities is using ActiveX.

The Microsoft Windows Server 2003 Internet Explorer Enhanced Security Configuration component (also known as Microsoft Internet Explorer hardening) reduces a server’s vulnerability to attacks from Web content by applying more restrictive Internet Explorer security settings that disable scripts, ActiveX components, and file downloads for resources in the Internet security zone.
(If you really want to read the full explanation, here is the original article)

This IE security setting is called "Binary and Script Behaviors" under the "ActiveX controls and plug-ins" category.

Figure 1

This setting is disabled in my case, which means using ActiveX is not an option. Now, you must wonder why this has anything to do with CSS opacity?

The "filter" attribute actually relies on ActiveX in order to mimic "opacity" in IE8 and below (discussed in stackoverflow). When the "Binary and Script Behaviors" setting is disabled, ActiveX became unavailable and the filter trick stopped working.

In Snippet 1, the filter is set to "alpha(opacity=40)", but when the "Binary and Script Behaviors" setting is disabled, filter will be ignored; and if background color is black, you will see a solid black instead of a semi-transparent black.

Figure 2

To reproduce this issue in IE8, first, you need to remove your app from the Trusted Sites (Figure 3). Then, disable "Binary and Script Behaviors" (See Figure 1).

Figure 3

The workaround is to set the "background-image" attribute to a semi-transparent PNG only for IE 7 to 8.

#trans {
  opacity: 0.4;
  /* filter: alpha(opacity=40); <-- Remove filter */
body.ie7 #trans, 
body.ie8 #trans {
  background: transparent url(/images/opacity40_black.png);
Snippet 2
The above CSS works with the following conditional body tags for marking IE versions.
<!--[if lt IE 7 ]><body class="ie6"><![endif]-->
<!--[if IE 7 ]><body class="ie7"><![endif]-->
<!--[if IE 8 ]><body class="ie8"><![endif]-->
<!--[if IE 9 ]><body class="ie9"><![endif]-->
<!--[if gt IE 9 ]><body class="ie10"><![endif]-->
<!--[if !IE]>--><body class="not-ie"><!--<![endif]-->
Snippet 3
To create a semi-transparent PNG, there are millions of PNG editing tools out there, but I found this free online generator is sufficient: Transparent PNG generator.

No comments:

Post a Comment