How to Make ClearType, @font-face Fonts and CSS Visual Filters Play Nicely Together

September 2nd, 2010 by zoltan · 17 Comments

Update (Sept. 3, 2010)

  • This article originally has the filter and -ms-filter rules reversed, which is against Microsoft’s best practices for IE8. This error has been corrected.
  • Thanks to Zoe Mickley Gillenwater for pointing out that IE8 needs to have all the filter functions (i.e. all the stuff in the double quotes) on one line.

The modern web developer wants to be able to use a variety of CSS3 effects together, but sometimes doing this in IE can be challenging, especially if you don’t want to use JavaScript. Let’s take a look a common problem with IE: blocky text in IE when using IE Visual filters on a block of text. For example, if you’ve ever tried to do the cross-browser CSS opacity trick to implement opacity in IE6, this problem manifests itself when the text is styled with no background color. A developer uses this well-known cross browser CSS-foo to make this work:

#badAntiAliasing {
	opacity: 0.5;

        /* IE 8 */
        -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(opacity=50)";

        /* IE 6,7 */
	filter: progid:DXImageTransform.Microsoft.Alpha(opacity=50);
	
}

And it looks great in every browser, but it looks like crap in Internet Explorer 6 with ClearType turned on. It is especially pronounced when using @font-face embedding with fonts that assume that some sort of anti-aliasing technology is being used. The example below uses Graublau Sans Web with the Alpha filter to illustrate the issue:

Opacity Solution in IE Opacity Solution in every other browser

This has been a known problem with IE ever since 2006 when ClearType’s product manager, Peter Gurevich, announced on the IEBlog their decision to disable ClearType on elements that use any Visual Filter. If you read the comments on this blog article, you will see many upset developers. I was one of them, since this not only affects the Alpha Filter, but all of IE’s Visual Filters, some of which I use in cssSandpaper to get IE to support CSS3 properties like transform.

Today, however, we can rejoice. There is a usable workaround that will make ClearType rendered fonts look nice when using Visual Filters. In our example above, here is what needs to be done:

body.ie6 #goodAntiAliasing,
body.ie7 #goodAntiAliasing,
body.ie8 #goodAntiAliasing {
	background-color: white;
}

#goodAntiAliasing {
	opacity: 0.5;

        /* IE 8: yes, it is ugly but it has to be on one line. :-( */
        -ms-filter: "progid:DXImageTransform.Microsoft.Chroma(color='white') progid:DXImageTransform.Microsoft.Alpha(opacity=50)";

        /* IE 6,7 is more flexible: it can be on multiple lines. */
	filter: progid:DXImageTransform.Microsoft.Chroma(color='white')
                progid:DXImageTransform.Microsoft.Alpha(opacity=50);
	
}

What is going on here?

  1. The first rule sets the background color of the container to a color that is represents the color of the majority of the background image on the page. Note that this rule uses Paul Irish’s Conditional CSS Pattern to serve it only to IE.
  2. The second rule executes two of IE’s Visual Filters:
    • the Chroma Visual Filter, which tells IE “Please make this color transparent”. The color we choose to make transparent is the one we selected in the first rule.
    • the Alpha Visual Filter, which does the opacity trick
Default Opacity in IE New Opacity Solution in IE

These filters must be in the order given, and not the other way around. Note also that care must be given that the color chosen to be transparent should be the average color of what is behind the text being styled, otherwise you will get less than optimal results. If this background is a complex image, just use the colour that’s used most often.

This fixes not only the IE opacity problem, but also issues with other Visual Filters, such as Matrix. I will be updating cssSandpaper to use this trick so that transformed objects in IE won’t look so blocky.

Take a look at the solution in action (make sure you look at it in IE in order to get the full effect)

Tags: @font-face · ClearType · CSS · CSS3 · Fonts · IE Visual Filters · , , , , , , , , , ,

17 responses so far ↓
  • 1 Pablo Lara H // Sep 2, 2010 at 4:28 pm

    Thank you for the sharing. As always, excellent post.

  • 2 Mathias // Sep 3, 2010 at 3:12 am

    Excellent research! Have you tried the shorthand notation for the opacity filter? I wonder if that would work in this scenario.

    body.ie6 #goodAntiAliasing,
    body.ie7 #goodAntiAliasing,
    body.ie8 #goodAntiAliasing {
    	background-color: white;
    }

    #goodAntiAliasing {
    	opacity: 0.5;
    	filter: progid:DXImageTransform.Microsoft.Chroma(color='white'),
    		    alpha(opacity=50);
    	-ms-filter: "progid:DXImageTransform.Microsoft.Chroma(color='white')",
    		    "alpha(opacity=50)";
    }

  • 3 zoltan // Sep 3, 2010 at 7:35 pm

    @Mathias: it does work with the older syntax, although I seem to remember Microsoft encouraging the longer syntax for some reason

    Note that my update on the filter syntax would apply here as well. My apologies for the confusion. Goes to show how preferable it is to use standards than to use a proprietary technology. ;-)

  • 4 Richard Fink // Sep 5, 2010 at 11:26 am

    Finally got over here to check it out, Zoltan. Great find. I’ll post about it and spread the word after I get back from Ireland.
    IE is a strange bird, really. I got started in web development in an Intranet environment with IE as the only approved browser so I know it intimately. It’s a pain in the ass to be sure, but very, very hackable. (High hopes for IE9.)
    Over the years I’ve found that if you look at IE’s features long and hard enough and then test enough, you can almost always get IE to “heal itself”. Judo style, you can use IE’s own peculiarities to overcome it’s peculiarities.
    Quite amazing.
    Great hack!

  • 7 Tim Binkley // Sep 17, 2010 at 6:53 pm

    Hi Zoltan –

    We’re having trouble with the font FFF Tusj on the Mac in Firefox and Safari. Do you think this code might offer a solution?

    Thank you.

    Regards,

    – Tim

  • 8 zoltan // Mar 5, 2011 at 4:32 pm

    @Tim: Unfortunately, this solution only fixes rendering problems in IE.

  • 9 Rebecca // Mar 8, 2011 at 8:51 pm

    You are a freaking legend.

    Thanks so much for posting it, I’d been looking for a fix for this for a while. Very glad I found your comment on another website linking here.

    Top job!

  • 10 zoltan // Mar 8, 2011 at 9:07 pm

    @Rebecca: I have never been called a legend before — thanks for the kudos. My friends also thank you in advance for the insufferably inflated ego I will almost certainly have for the next few days. Cheers! :)

  • 11 Jennifer // Aug 10, 2011 at 8:26 pm

    So, we are having the issue when a container has the box-shadow filter applied. How would your solution work there? We’re not trying to do anything to the text, just have drop shadows on our containers. Ideas? Thanks if so.

  • 12 zoltan // Aug 14, 2011 at 10:15 am

    @Jennifer: Using the DropShadow filter on this container will do this trick, as long as you set a background color to the object, otherwise IE6-8 will put a drop shadow on the text as well. In order to handle transparent backgrounds in IE6-8, one must use the Chroma filter alomg with the DropShadow filter in order to make this work. Here is an example of this in action:

    http://www.useragentman.com/tests/boxShadow/crossBrowser.html

    View the source to see the full CSS with a brief explanation. I will probably end up writing an additional blog post about this method so I can explain in detail.

  • 13 zoltan // Sep 24, 2011 at 2:18 pm

    @cheryl: in your -ms-filter, make sure you don’t forget the “#”, as in:


    .maintext {
    -ms-filter: “progid:DXImageTransform.Microsoft.Chroma(color=’#e5ffe2′)”;
    }

    You will also need to add a background-color: #e5ffe2; above it to make it work correctly. All these rules should be in an IE-only CSS rule, since this code will produce different results in other browsers.

  • 14 Evan // Oct 12, 2011 at 3:40 pm

    Oh man, Thanks for sharing this fix. I couldn’t figure it out for the life of me. It almost makes sense – wonder if anti-aliasing is related to the transparency issues, and once you set a bg color for it it can calculate the smooth edges? I don’t know, but it does work. and thank you!

  • 15 Chris // Sep 18, 2012 at 9:21 am

    I can’t get this to work when using -sand-transform:rotate() on the same element – although if I copy the -sand-transform generated rotation rule, append this within the same filter: parameter and add it to the stylesheet manually it does work.

    Is there a way to pass this through -sand-transform to get the required effect?

    e.g.
    background-color: white;
    filter: progid:DXImageTransform.Microsoft.Matrix(M11=0.998630, M12=0.052336, M21=-0.052336, M22=0.998630, sizingMethod=’auto expand’)
    progid:DXImageTransform.Microsoft.Chroma(color=’#ffffff’);

    Many thanks.

  • 16 zoltan // Sep 18, 2012 at 5:27 pm

    There is a -sand-chroma-override property that you can use to implement this fix. For example, setting -sand-chroma-override: #808080 sets the background of the object to #808080 in IE and then removes that background color using the Chroma filter. See cssSandpaper’s official documentation for more info.

Give Feedback

Don't be shy! Give feedback and join the discussion.

Please Note: If you are asking for help using the information on this page or if you are reporting a bug with the code featured here, please include a URL that shows the problem you are experiencing along with the browser/version number/operating system combination where the issue manifests itself. Without this information, I may not be able to respond.

An orange star denotes a required field.