Cross-browser opacity

With the rapid proliferation of IE 7, I think a closer look at cross-browser opacity is needed.

Please note that I’m not talking about image-based opacity, but rather opacity on any given element. There are articles on image opacity that are still relevant to today’s browsers.

The current favorite method is a combo opacity/filter fix to placate Gecko and Webkit browsers, as well as IE 6 and below. This involves setting a opacity value for browsers that support the spec, and hacking out an acceptable solution for browsers that don’t (read: <IE6). The fix is outlined below:


  <style type="text/css" media="screen">
    #element {
      opacity: 0.5;
      -moz-opacity: 0.5;
    }
  </style>
  
  <!--[if lte IE 6]>
  <style type="text/css" media="screen">
    #element {
      filter: alpha(opacity=50);
    }
  </style>
  <![endif]-->

As you can see, the code is quite verbose for what it is. Let’s take it step-by-step. The first style block contains the supported opacity properties for Safari and Opera (opacity), as well as Gecko-based Firefox and Camino (-moz-opacity).

The latter block is designed so that only Internet Explorer receives that code (in real-world application, this code would appear in a separate “<IE 6 only” style sheet. The block contains a proprietary property called “filter”, supported by Microsoft browsers. This property is not approved by the W3C, and is therefore invalid. Thus the need to “hide” it from validators and place it in its own style sheet.

While the code is slightly complex, it has served its purpose. But with the evolving nature of the web, its status has changed since this method was concocted. New browsers have emerged, others have updated. Essentially the web has changed enough that we must tweak this fix in order to get true cross-browser opacity. There are a few ways to handle this depending on your preference and whether or not you care about style sheet validation. Lets take a look, first at the browser changes, and at a couple of updated fixes:

Internet Explorer 7

Its characteristics are impressive. It supports quite a bit more W3C approved properties than it’s predecessor. However, the powers-that-be decided that it would not support the opacity properties– not yet, anyway.

On the other hand, IE 7 does still support the proprietary filter property. This means that IE 7 will respond to the same fix created for IE 6.

However, one of the many improvements IE 7 brings to the table is its native support for PNG transparency. This is an important point, as it allows us to devise a fix that will play better for those not interested in yet another conditional comment.

Gecko-based browsers (Firefox, Camino)

Gecko browsers support their own proprietary CSS property, the -moz-opacity property. However, it’s no longer necessary to declare this property, since current versions now include support for the standard opacity property.

So, given these bits of info, we’re left with the following cross-browser opacity methods:

The single conditional comment fix

The simplest method of all these is to simply remove the -moz-opacity property and open up the IE conditional comment to include IE 7. Example below:


  <style type="text/css" media="screen">
    #element {
      opacity: 0.5;
    }
  </style>
  
  <!--[if lte IE 7]>
  <style type="text/css" media="screen">
    #element {
      filter: alpha(opacity=50);
    }
    #someOtherElement {
      height: 1%;
      margin-left: -3px;
    }
  </style>
  <![endif]-->

While this is an easy solution, it is not often the best. For example, your CC was probably specified for IE 6 and below for a reason. Remember that IE 7 is much more standards-aware than previous IE incarnations, and probably does not need any of the hacks defined in the <IE 6 stylesheet. Thus, you’d most likely have to do some more work hiding those hacks from IE 7.

The multiple conditional comment fix

Another method is to create another stylesheet, and wrap it around an IE 7 conditional comment:


  <style type="text/css" media="screen">
    #element {
      opacity: 0.5;
    }
  </style>
  
  <!--[if lte IE 6]>
  <style type="text/css" media="screen">
    #element {
      filter: alpha(opacity=50);
    }
    #someOtherElement {
      height: 1%;
      margin-left: -3px;
    }
  </style>
  <![endif]-->
  
  <!--[if IE 7]>
  <style type="text/css" media="screen">
    #element {
      filter: alpha(opacity=50);
    }
  </style>
  <![endif]-->

This fix addresses the problems of the earlier fix, but creates additional markup, not to mention yet another stylesheet to maintain. If all the IE 7 stylesheet does is add opacity support, it would hardly be in your best interest to keep it around.

The IE 7 filter fix

There is another way to support IE 7, and that involves using an IE 7 CSS filter to target only that browser:


  <style type="text/css" media="screen">
    #element {
      opacity: 0.5;
    }
    *:first-child + html #element {
      filter: alpha(opacity=50);
    }
  </style>
  
  <!--[if lte IE 6]>
  <style type="text/css" media="screen">
    #element {
      filter: alpha(opacity=50);
    }
  </style>
  <![endif]-->

This works a treat, but it also carries the inconvenience of invalidating your style sheet.

The PNG transparency fix

This is my favorite method, merely because it eliminates the issues of the first three methods. However, that’s not to say it doesn’t come with it’s own flaws:


  <style type="text/css" media="screen">
    #element {
      background: url("/path/to/image.png");
    }
  </style>
  
  <!--[if lte IE 6]>
  <style type="text/css" media="screen">
    #element {
      filter: alpha(opacity=50);
    }
  </style>
  <![endif]-->

This method eliminates the opacity property altogether, and instead relies on a transparent PNG to mimic transparent color. Because IE 7 supports native PNG transparency, the fix works for all advanced browsers. The <IE 6 stylesheet is left alone, since it’s PNG support leaves much to be desired.

The downside of this method, of course, is that you lose the ability to easily update the element you are editing. Rather than changing a hex value, or tweaking the opacity value, you’d have to go through your photo editor and change a PNG in order to see changes.

So there you have it, four distinct ways to implement cross-browser opacity. Each with its benefits, each with its flaws. It’s ultimately up to you to weigh those against each other, and choose what best fits your needs.

del.icio.us:Cross-browser opacitydigg:Cross-browser opacity

14 Comments

  1. roxanne
    March 10, 2007
    10:27 am
     

    Excellent information and understandable. Thanks so much for this useful article. I look forward to more.

  2. roxanne
    March 11, 2007
    9:28 pm
     

    i tried the third method on the headerbar here http://roxstyle.com/ but it seems to mess up the link style of the list within the element.

  3. doctyper
    March 12, 2007
    7:10 am
     

    Opacity on an element means the element and its children will retain the transparent value. Your list is a child of the headerbar, which means it will also become transparent.

  4. HelloWorld
    April 28, 2007
    1:51 am
     

    Peace people

    We love you

  5. nicky v
    May 15, 2007
    8:03 am
     

    thank you this was really helpful

  6. John Lascurettes
    January 4, 2008
    4:55 pm
     

    BTW, you haven’t needed -moz-opacity since +before+ gecko 1.7 (which is what was used in Firefox 1. 0). Use simply opacity: for all modern gecko browsers (firefox), webkit browsers and Opera.

  7. John Lascurettes
    January 7, 2008
    9:22 am
     

    Also, note that any Windows version of IE will only accept the filter:opacity() value if the element it is being applied to also hasLayout: http://www.satzansatz.de/cssd/onhavinglayout.html

  8. Troy III
    June 9, 2008
    4:31 pm
     

    Explorer inroduced OPACITY back in ancient 1997.
    W3C bastards, after e decade decided to reinvent the wheel and teach Einstein how to call his own “Special Theory of Relativity”. Because from now on, “it will be called *our discovery*”!

    By the way, your redoundant code sucks. Especially your margin left -3px.
    There is no need to hide anything, -who gives a shit that netscape loosers decided to forcedly yeld a CSS error in their browser. (Wich, by the way – is aganist the rules of CSS) But anyhow. The page will display and function perfectly on any rigid and lazy Netscape bastard breed.

    the css:
    ~~~~~~~~~~~~~~~~~~~~~~~
    filter: alpha(opacity=50);
    -moz-opacity: .5;
    -khtml-opacity: .5;
    opacity: .5;
    ~~~~~~~~~~~~~~~~~~~~~~~
    will do just fine…

  9. doctyper
    July 16, 2008
    3:23 pm
     

    Wow, Troy. So bitter.

    Do remember that this article was written more than A YEAR AGO. And thanks for pointing out my redoundancy [sic].

  10. Matthew Edmunds
    September 10, 2008
    9:40 pm
     

    Hi, I am doing fine with Firefox using opacity to create roll overs. I can’t make it work in ie7

    I am guessing it is because I am not using the #element and am assigning a class.

    a.button:hover {opacity: 0;-moz-opacity:0.0;}
    a.button:visited {opacity: 0.4; -moz-opacity:0.4;}

    a.button:hover {filter: alpha(opacity=00);}
    a.button:visited {filter: alpha(opacity=40);}

    Is there a way around this for IE7? or is it simply not supported?

    It is very succinct and simple method to create a rollover using 1 image in the BG and controlling the opacity of the image over it rather than using the old fashioned java style rollovers.

    Thank you for your help with this.

    Matthew

  11. Martin
    February 27, 2009
    2:53 pm
     

    And look al that nasty html comments just for IE.. what a wonderful world huh..

    microsoft is just a reflex of their users :P

    thanks for the info man! You are the one! :)

  12. Shaishav
    August 11, 2010
    11:04 pm
     

    Thanks – very useful!

  13. dfbjhsbdjfhbsdjfhbds
    March 28, 2011
    6:04 pm
     

    Just have one question! Why all of you keep asking email and using this bullshit sentence: “will not be published”, hum??? If i want an answer I just put my email or even better conmtact you, if not I will just SIMPLY LIE! And use one like this one: dfbjhsbdjfhbsdjfhbdsjhfbsd@gmail.com

  14. dfbjhsbdjfhbsdjfhbds
    March 28, 2011
    6:07 pm
     

    But anyway I love your website clean interface!
    Peace dude and please take off this “required fields”. I hate this mass standardization and globalization, is so kitsch and so predictable to evoke a mystified concept from it.

Post a Comment

Your email is never published nor shared. Required fields are marked *
*
*