Grow your CSS skills. Land your dream job.

CSS Transparency Settings for All Browsers

Published by Chris Coyier

Transparency is one of those CSS properties that has a weird history and requires lots of different properties and values to ensure cross browser compatibility that goes back as far as you can. To cover all your bases, you need a bunch of CSS statements. Fortunately they don't interfere with each other, so using them all every time you wish to add transparency is no big hassle and worry-free. Here they are, and are currently set to 50% transparency:

.transparent {
	/* Required for IE 5, 6, 7 */
	/* ...or something to trigger hasLayout, like zoom: 1; */
	width: 100%; 
		
	/* Theoretically for IE 8 & 9 (more valid) */	
	/* ...but not required as filter works too */
	/* should come BEFORE filter */
	-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=50)";
	
	/* This works in IE 8 & 9 too */
	/* ... but also 5, 6, 7 */
	filter: alpha(opacity=50);
	
	/* Older than Firefox 0.9 */
	-moz-opacity:0.5;
	
	/* Safari 1.x (pre WebKit!) */
	-khtml-opacity: 0.5;
    
	/* Modern!
	/* Firefox 0.9+, Safari 2?, Chrome any?
	/* Opera 9+, IE 9+ */
	opacity: 0.5;
}
Update July 5, 2011. Here's what I'd recommend for usage today, in way easier copy-and-pasteable format.
.transparent {
	zoom: 1;
	filter: alpha(opacity=50);
	opacity: 0.5;
}

Comments

  1. Permalink to comment#

    I’ve tried to use this on links as the following :

    a img:hover {
    filter:alpha(opacity=50);
    -moz-opacity:0.5;
    -khtml-opacity: 0.5;
    opacity: 0.5;
    }

    Unfortunately, it does not work on IE. Do you know how to overcome this problem?

  2. I think your problem you are applying the pseudo class :hover to the img element not the anchor element. IE doesn’t support pseudo classes on img elements I don’t think.

    You could try setting up a class (e.g. “transeffect”) for the anchors you want to have this transparency rollover effect on and then changing your CSS to:

    a.transeffect:hover {
    filter:alpha(opacity=50);
    -moz-opacity:0.5;
    -khtml-opacity: 0.5;
    opacity: 0.5;
    }

  3. anonymous
    Permalink to comment#

    No it’s not that, IE does support the onhover stuff, fortunately.

    There’s a bug in IE 6 + 7 (perhaps older versions too — haven’t checked) that prevents the filter / opacity to be applied on elements when there is no dimension property assigned in CSS.

    One way to bypass that bug is to use JavaScript, then it suddenly works. Or just specify a height / width when it doesn’t conflict with the stylesheet.

  4. Ah yes, that would work. You maybe be able to set the width to like 99.9% to trigger it as well, instead of setting an fixed width when you don’t want to.

  5. Volkan Görgülü
    Permalink to comment#

    -moz-opacity:0.5;
    -khtml-opacity: 0.5;

    Hi Chris, these two lines are for which browsers?

  6. the -moz-opacity selector is for way old versions of the Mozilla browser (Netscape). This still works and is necessary for those browsers.

    the -khtml-opacity selector is a little stranger. I originally picked it up when working with JonDesign’s SmoothGallery for the first time, where he uses it for a few rollover transparencies. I believe -khtml is specifically for Safari 1.x.

  7. I use:
    filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=”images/background.png”, sizingMethod=”scale”);

  8. I’d love to see some live examples of these styles in action. I was thinking it might be neat to have a floating div with the random letters of half a secret message, with the other half of the letters in a background image or something so you’d have to scroll down to exactly the right point in order to reveal the full message. I’m still fairly new to CSS myself, though, so I can’t think through how to make it happen.

  9. Gagan
    Permalink to comment#

    Dont forget DOCTYPE to make it work with IE7 ;)

    add this to your html to make it work with IE7

  10. Permalink to comment#


    the -khtml-opacity selector is a little stranger. I originally picked it up when working with JonDesign’s SmoothGallery for the first time, where he uses it for a few rollover transparencies. I believe -khtml is specifically for Safari 1.x.

    Well its not specifically for Safari, the linux webbrowser Konqueror is also based on the khtml kit.

  11. shane
    Permalink to comment#

    If use transparency on a block element it makes the text inside transparent as well – is there a way i can prevent that from happening?
    I tried putting the text in another div and setting the opacity to 100 but that didn’t do the job, although, logically, i thought it would…

  12. fioge
    Permalink to comment#

    You can’t use nested div since it inherits parents opacity level as his 1.0-opacity. You should use the same level foreground div, absolutely positioned over transucent background div, with higher z-index.

  13. Robert
    Permalink to comment#

    You can use a nested div to get non-transparent text over semi-transparent background if you turn the opacity on the inner div back up, and set the background-color to transparent:
    test
    See my goofing around/learning/hack page: http://www.aedsnet.com/ajaxmap.html
    (click on a map-marker to see the semitransparent box).

    At least, it worked in IE7 and FireFox

  14. Robert
    Permalink to comment#

    OK, that link should be http://www.aedsnet.com/maps/ajaxmap.html

    Also, I didn’t realize the html I put into my comment would not display as text,
    so this is what I have as properties for my “nested div”:
    style=”opacity:1; background: transparent;”
    The parent div has a green background with opacity of 0.8

    But surely it can’t be that simple?

  15. @Robert: It looks like the text inside your transparent boxes are picking up the transparency as well. You cannot “turn back up” the transparency of child elements, unfortunately.

    I did a little tip on how to deal with the recently: Non-Transparent Elements Inside Transparent Elements.

  16. Permalink to comment#

    Well… this is well-known indeed but this is NOT valid CSS! Maybe a transparent png as a background along with a js library to handle IE case would be better

  17. Permalink to comment#

    Thx for the info and tips Chris Coyier

  18. Permalink to comment#

    in ie6 :hover works only with a link. this will work for you though:

    a:hover img {
    filter:alpha(opacity=50);
    -moz-opacity:0.5;
    -khtml-opacity: 0.5;
    opacity: 0.5;
    }

  19. dipak
    Permalink to comment#

    I have a checkbox and i want that checkbox to have opacity 0.5. I am using Mozilla 1.4 browser in Solaris 9. But the checkbox is not getting displayed for ‘-moz-opacity:0.5;’. It does not consider values in the range 0 or 1. For values less than 1 checkbox is not getting displayed. Please tell me the solution , if in solaris 9 i can use another property.

    current style class for checkbox:
    {
    filter:alpha(opacity=50);
    -moz-opacity:0.5;
    -khtml-opacity: 0.5;
    opacity: 0.5; }

  20. In my CSS i have something like this:

    {
    position: absolute;
    height: 99%;
    width: 25%;
    cursor: pointer;
    z-index:10;
    filter:alpha(opacity=20);
    -moz-opacity:0.2;
    -khtml-opacity: 0.2;
    opacity: 0.2;

    but SmoothGallery still looks awful in Konqueror and Opera. Any way to fix this?

  21. zombie
    Permalink to comment#

    FOR THE FIRST COMMENT , you should do like this , and it will work in all browsers =>

    a:hover img {
    filter:alpha(opacity=50);
    -moz-opacity:0.5;
    -khtml-opacity: 0.5;
    opacity: 0.5;
    }
  22. Thanks a lot for this tip. I am using it for a menu div over a picture, it looks really cool.

  23. Ah, when I have a CSS question I should just search your archives instead of Google. I thought I was knowledgeable in CSS until I read your blog… you rock!

    Cheers for the info!

  24. Very handy for my navigation, saves a css sprite.
    Nice design by the way!

  25. Peter Yee
    Permalink to comment#

    Hi, i tried the codes and it looks great on moz and safari, but in ie, its lagging each time u hover it… help!!!

  26. Important!

    An element must have page layout in IE6 is you want to use opacity! You do this by using the star html hack and giving the element a height value of 1px. Because IE6 is stupid, the height will stretch regardless and all other browsers will ignore it.

    If the element doesn’t have page layout, your opacity styles will have no effect at all.

  27. mbhayes
    Permalink to comment#

    Okay Chris … several situational comments appear to have been made … you have any further summary / conclusion (to tie-up all of these loose ends)? Or should we just consider your code at the top a good general starting point that’ll have to be situationally tweaked?

    Thanks

  28. Permalink to comment#

    Great this is just what I need. Thanks a lot!

  29. Permalink to comment#

    I just tried you method now and it work’s great .Thank you very much!!!!

  30. Ze Thriller
    Permalink to comment#

    Never use opacity directly on an image, set it instead on a div containing the image, this will greatly help to make a clean and fully compatible code.

    Example:

    <div style="filter: alpha(opacity=50);">
        <img src="a.png" alt="" width="100" height="100" />
    </div>
    

    If you plan on using RGBA PNG images (RGB with transparency layer, not indexed) in an IE6-compatible application, it is needed to use DirectX (DX6 or above required) image filters, but I don’t recommend it at all exept for this special case.

    Example:

    <span style="width: 100px; height: 100px; filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='a.png', sizingMethod='scale');">
        <img src="transparent.gif" width="1" height="1" alt="" style="display: block;" />
    </span>
    

    Note the span containing the filter. The inner image is a transparent filler 1px x 1px (smallest size). I noticed it was better than a   (non-breakable space) because of zoom text (can break design) and the unability to set a 1px sized text.

    I found a JavaScript code that can replace all your PNGs in the page, I just changed it a bit to handle IE8. Works fine and quite fast, althrough there are some limitations:
    – Images inside display: none elements will not be affected (IE bug ?). It may be the same with visibility: hidden and opacity=0, test yourself.
    – Image are changed after all the page has loaded. The script will start even if loading has been interrupted by the user (ESC key, …) or some images are missing or unreachables.
    – Once modified, images are no more IMG tags but SPAN: it becomes impossible to set image properties directy via scripting (JavaScript, Visual Basic, …) if image-specific codes are used:

    Wrong (JavaScript code):

    document.getElementById('myimage').src = 'b.png';
    

    Correct (JavaScript code, a bit bigger):

    var img = document.getElementById('myimage');
    if (img.nodeName.toLowerCase() == 'span') // <span> tag ?
    {
        img.style.filter = 'progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\'b.png\', sizingMethod=\'scale\')';
        // Change "image" dimensions if needed (example, optional):
        img.style.width = '100px'; // Don't forget the unit !
        img.style.height = '100px'; // Same here
    }
    else
    {
        img.src = 'b.png'; // Standard method (much easier !)
    }
    

    Try to make a function of this if used many times.

    PNG auto transform script (here is an XHTML fragement):

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <html>
    <head>
    <title>IE6 PNG loader test page</title>
    <script type="text/javascript">
    // <![CDATA[
    function correctPNG()
    {
        if ((navigator.appName == 'Microsoft Internet Explorer') && (navigator.appVersion.indexOf('MSIE 7') == -1) && (navigator.appVersion.indexOf('MSIE 8') == -1)) // IE < v7.x (+ Maxthon v1.x/v2.x , AOL , ...)
        {
            for(var i=0; i<document.images.length; i++)
            {
                var img = document.images[i]
                var imgName = img.src.toUpperCase()
                if (imgName.substring(imgName.length-3, imgName.length) == "PNG")
                {
                    var imgID = (img.id) ? "id='" + img.id + "' " : ""
                    var imgClass = (img.className) ? "class='" + img.className + "' " : ""
                    var imgTitle = (img.title) ? "title='" + img.title + "' " : "title='" + img.alt + "' "
                    var imgStyle = "display:inline-block;" + img.style.cssText
                    if (img.align == "left") imgStyle = "float:left;" + imgStyle
                    if (img.align == "right") imgStyle = "float:right;" + imgStyle
                    if (img.parentElement.href) imgStyle = "cursor:pointer;" + imgStyle
                    var strNewHTML = "<span " + imgID + imgClass + imgTitle
                    + " style=\"" + "width:" + img.width + "px; height:" + img.height + "px;" + imgStyle + ";"
                    + "filter:progid:DXImageTransform.Microsoft.AlphaImageLoader"
                    + "(src=\'" + img.src + "\', sizingMethod='scale');\"><\/span>"
                    img.outerHTML = strNewHTML
                    i = i-1
                }
            }
        }
    }
    // ]]>
    </script>
    </head>
    <body onload="correctPNG();">
    <!--- Main content -->
    <div><img src="a.png" width="100" height="100" alt="" /></div>
    </body>
    </html>

    I rather use body onload than its JavaScript equivalent (window.onload), seems to work much better, with increased stability.

  31. anastasia
    Permalink to comment#

    this is awesome, thanks for the help.

  32. Permalink to comment#

    IS there a way to apply transparency on a background image? as in

    example:

    background: url(image.gif) repeat-x bottom left;
    opacity: 0.4;
    filter: alpha(opacity=40);

    ???

  33. sam
    Permalink to comment#

    This will not work for ex. in a subnavigation when the png is behind an a tag. the a tag will not work as long you ll not position it relatively what is not always possible. but yeah… theoretically it would work.

  34. sam
    Permalink to comment#

    in IE6 :D. where else…

  35. sam
    Permalink to comment#

    .transparent_class {
    filter:alpha(opacity=50);
    -moz-opacity:0.5;
    -khtml-opacity: 0.5;
    opacity: 0.5;
    }

    I have an other question related to the topic. Using "opacity" on an element (lets say div) will apply the opacity on all child elements too. Is there a way around that?

    cheers

  36. Sil
    Permalink to comment#

    Thank you :D

  37. Permalink to comment#

    Hey, this is exactly what I was looking for! This opacity crap is a pain in the ass, but you pulled it all together in a succinct post.

  38. Permalink to comment#

    Right now, am messed with one my website css strcuture, and was searching on google “how to set website on all browsers using css”

    though it wasn’t proper solution but i find out the another bug just because of your nice tutorials :)

    Thanks for your nice tuts!!!

  39. Permalink to comment#

    What a great script! I was thinking that couldn’t be realized transparency in all browser, but now this script has changed my mind. Thanx.

  40. David
    Permalink to comment#

    Hi Sam in answer to your question try this:

    .myelement {
    background: rgba(200, 54, 54, 0.5);
    }

    reason:

    The opacity style affects the whole element and everything within it. So if you do not want opacity cascading this is a useful solution:

    source: http://stackoverflow.com/questions/5662178/opacity-of-divs-background-without-affecting-contained-element-in-ie-8

    • Michael
      Permalink to comment#

      David! You’ve just answered a five year old question :)

  41. parmacetti
    Permalink to comment#

    And thanks for the answer, David – I was just looking for that info!

  42. I’d like to highlight one important fact about IE. When testing I found out that:

    -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#99000000, endColorstr=#99000000)"; sets opacity ALSO for the children of a given DOM Element. i.e, given: will make div 1 alpha transparent and also 2 will be alpha transparent.

    BUT if you want to mimic rgba alpha, for a 0.5 transparent background (that is, children will have their OWN opacity), you’d better use:
    filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#66ffffff,endColorstr=#66ffffff);

    So, let’s say the difference is that -ms-filter mimics W3c opacity property, and filter mimics rgba color system

This comment thread is closed. If you have important information to share, you can always contact me.

*May or may not contain any actual "CSS" or "Tricks".