Giving Challenged @font-face Fonts The Italics Makeover

September 7th, 2010 by zoltan · 5 Comments

See the nice italicized text in the heading of this article? It is not so obvious to style as you may think. There are many great free and commercial fonts out there that allow @font-face embedding. Unfortunately, not all of them have an italics variant for one reason or another. For example, the font I use for my blogs headlines, Graublau Sans Web, does not have a true italics variant included with it, while the font I use for the blog’s copy, Droid Sans, does. When a font doesn’t have an italics variant, and you try to italicize it in a web-page using <i> and <em> tags, the results depend on the browser you are using:

  • Safari, Chrome and Opera will render the font normally without italicizing it.
  • Internet Explorer and Firefox will attempt to italicize the font, but Internet Explorer will slant the font at a 20° angle while Firefox implements a 10° slant.
Internet Explorer 6.0 Firefox 3.6 Safari 4/Chrome 5/Opera 10
Default Italics for Graublau Web in IE. Default Italics for Graublau Web in Firefox. Default Italics for Graublau Web in Safari.

This inconsistency is quite annoying from a user-experience point of view. However, there is a way of leveling the playing field by using the CSS3 transform property. And even though Internet Explorer doesn’t recognize transform, there is a workaround without using JavaScript using the Matrix Visual Filter.

The CSS

When I was a calligraphy student, I learned that the Italics script was to be written on a 10° angle. Using the CSS3 transform property, this can be achieved by using the skewX() function:

#content h1 em {
    font-family: "Graublau Web Bold", Arial, sans-serif;
    font-style: normal;
	
    -moz-transform:    skewX(-10deg);
    -o-transform:      skewX(-10deg);
    -webkit-transform: skewX(-10deg);
    transform:         skewX(-10deg);
    
    display: inline-block;

}
	

The display: inline-block is there since Safari, Chrome and Opera will not allow transformations on an inline element.

But what about Internet Explorer? I could use my cssSandpaper script, but it is really simple to do without it:

#content h1 em {
    font-family: "Graublau Web Bold", Arial, sans-serif;
    font-style: normal;
	
    -moz-transform:    skewX(-10deg);
    -o-transform:      skewX(-10deg);
    -webkit-transform: skewX(-10deg);
    transform:         skewX(-10deg);

    display: inline-block;

    /* IE8+: must be on one line. */ 
    -ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=1, M12=-0.1763269807084645, M21=0, M22=1, SizingMethod='auto expand')";
    
    /* IE6 and 7 */ 
    filter: progid:DXImageTransform.Microsoft.Matrix(
             M11=1,
             M12=-0.1763269807084645,
             M21=0,
             M22=1,
             SizingMethod='auto expand');
}
	

This is the Microsoft Matrix Filter equivalent of skewX(10deg). Let’s take a look at how this works in all the major browsers:

Internet Explorer 6.0+ Firefox 3.5+ Safari 4+ Chrome 5+ Opera 10.5+
Italics Fix in IE Italics Fix in Firefox Italics Fix in Safari Italics Fix in Chrome Italics Fix in Opera

Isn’t that nice and consistent? The screenshots are from the Windows versions of the browsers, but you can expect the same results for Mac and Linux versions as well.

Is This Really Italics?

Not really. Technically, we are creating an oblique variant of this font. The Wikipedia entry for Oblique fonts states that many sans-serif fonts do not have italic variants, so this technique will be a useful one in a web developers toolkit.

Caveats

  • If you are going to make a few words in a row oblique, make sure you wrap the <i> and <em> tags around each word. This is because the display: inline-block rule treats multiple words wrapped in one set of these tags as one word, which will cause problems when you want the words to wrap to the next line.
    Wrapping multiple words with one <em> tag
    Bad Word Wrap Example
    Wrapping multiple words with separate <em> tags
    Good Word Wrap Example
  • If the oblique text does not have a solid background color, it will appear “blocky” or “pixely” in IE. To fix this, you must use IE’s Chroma Visual Filter, as described in my last blog post, How to Make ClearType, @font-face Fonts and CSS Visual Filters Play Nicely Together.
  • In IE, multiple oblique words may appear to have more white space than the other browsers. In this case you may need to create IE-only CSS rules that implement negative left margin on each word, using a solution like Paul Irish’s Conditional CSS Pattern.
  • Webkit browsers apply the slanting correctly if a font-style: normal is declared in the @font-face rule for the font (thanks to Raph Levien for commenting on this below.

Tags: @font-face · CSS · CSS3 · Fonts · transform

5 responses so far ↓
  • 1 Raph Levien // Sep 20, 2010 at 1:39 pm

    Great writeup! One additional data point you may be missing. Webkit browsers _would_ be applying the slanting correctly if you specified “font-style: normal” in the @font-face rule for the font. This is documented in http://paulirish.com/2010/font-face-gotchas/

  • 3 Lukas // Feb 3, 2011 at 8:32 am

    Hovering over the title in the articles list (FF 4.0b10) causes everything to be underlined except things in em tags. also the tooltip shows the em tags ^^

  • 4 zoltan // Mar 5, 2011 at 4:07 pm

    @Raph: thanks for the note (and for moderating this so late — missed this one). Good tip – will update the article.

  • 5 Julio // Aug 25, 2011 at 9:22 am

    That’s perfect!

    A just didn’t want to add more weight to the site adding another font file. Voilà!

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.