Cross-browser Web Fonts – Part 3

Chris Mills
Share

Widespread browser support for @font-face has done wonders for web typography, allowing us the freedom to use custom fonts wherever we want. But different fonts are not the whole story with web typography. There are other things that the web has long been weak at, such as proper hyphenation of long words, and usage of open type font features such as ligature and stylistic swashes that often get locked away inside font files and never see the light of day.

In this article we will look at some of these new CSS font features.

hyphenation

This section could also be named something like “solving the problem of justified text/long words looking awful in text columns” … but that would sound really terrible too, so I just stuck with plan A. In brief, the problem lies with the fact that, for years, there has been no decent way to use text-align: justify without it looking awful.

Hyphens Before

Fortunately there are now ways to deal with the problem, which work across most browsers you might have in your support matrix. The best of these is the CSS3 hyphens property, which adds typographically appropriate hyphens where needed, giving a nice visual clue that the word continues on the next line. It also makes an effort to break words that don’t quite span the full width of the column, effectively reducing the rivers-of-whitespace effect. The code looks like so:

p { 
  font-size: 2.1em; 
  text-align: justify;  
  -webkit-hyphens: auto; 
  -moz-hyphens: auto; 
  -ms-hyphens: auto; 
  hyphens: auto; 
}

Hyphens After

There are other values for the hyphens property too: none will turn off hyphens if they have already been set somewhere else, and manual will cause words to break only when manual hyphens have been set on the words using the ‐ or ­ characters.

Below is a demo, which you’ll have to view in a supporting browser:

See the Pen Hyphenation example by SitePoint (@SitePoint) on CodePen.

text-rendering

The text-rendering property provides information to the browser’s rendering engine to indicate what to optimize for when rendering text. The possible values are:

  • auto: Allows the browser itself to make a decision about when to optimize for speed, legibility, and geometric precision while drawing text. WebKit/Blink browsers generally treat this as optimizeSpeed (see below), whereas Gecko uses optimizeSpeed when rendering text of 20px or smaller, and optimizeLegibility when rendering text larger than that.
  • optimizeSpeed: The browser puts speed first, disabling expensive features such as kerning and ligatures.
  • optimizeLegibility: The browser puts legibility first, enabling features such as kerning and ligatures when they are available in the font you are using.
  • geometricPrecision: The browser puts geometric precision first, meaning that certain aspects of fonts that do not scale linearly — such as kerning — can be made to scale more smoothly at different zoom sizes. Gecko treats this value the same as optimizeLegibility.
p { 
  text-rendering: optimizeLegibility; 
}

These features are supported in Firefox, Chrome, and Safari, with the caveats listed above.

font-feature-settings

font-feature-settings is a great new property that allows you to control the usage of the cool alternative glyphs residing inside your open type font files (some of them, anyway) such as ligatures and stylistic swashes, which otherwise wouldn’t see the light of day.

How do you know what font features are available?

Good question. This used to be pretty difficult, as font foundries seemed surprisingly bad at communicating such information. Fortunately more recently this information has been made more readily available, for example via hosted font services such as Fontdeck.

Fontdeck Info

Once you know what your font has available, you can start turning said font features on and off, using the font-feature-settings property. Its value takes the form of a list of codes that represent the different features you want to use, so for example:

p { 
    -webkit-font-feature-settings: "dlig" 1, "kern" 1, "frac" 1; 
    -moz-font-feature-settings: "dlig" 1, "kern" 1, "frac" 1; 
    -ms-font-feature-settings: "dlig" 1, "kern" 1, "frac" 1; 
    font-feature-settings: "dlig" 1, "kern" 1, "frac" 1; 
}

Firefox and IE11 no longer need the prefixed version, but I’ve left those in for the benefit old older versions that might. Blink and WebKit browsers still need the prefix, and so does IE10.

Let’s look at the different options available in font feature settings.

Ligatures and discretionary ligatures

These take the form of stylistic joins between appropriate letter couplets, such as “oo” and “th”.

p { 
    -webkit-font-feature-settings: "liga" 1, "dlig" 1; 
    -moz-font-feature-settings: "liga" 1, "dlig" 1; 
    -ms-font-feature-settings: "liga" 1, "dlig" 1; 
    font-feature-settings: "liga" 1, "dlig" 1; 
}

dlig Before

dlig After

The above image shows discretionary ligatures (dlig) applied to Monarcha Book from Fontdeck.

Numerals, fractions, and ordinals

There are a number of different open font features that change the presentation of numerals in many advantageous ways. For example:

p { 
    -webkit-font-feature-settings: "onum" 1, "tnum" 1, "frac" 1; 
    -moz-font-feature-settings: "onum" 1, "tnum" 1, "frac" 1; 
    -ms-font-feature-settings: "onum" 1, "tnum" 1, "frac" 1; 
    font-feature-settings: "onum" 1, "tnum" 1, "frac" 1; 
}

Again, using our Monarcha font from Fontdeck, let’s examine a few interesting numeral variations.

In my experience, tabular numerals (tnum) and proportional numerals (pnum) tend to look very similar, and the intended effect is quite similar. Tabular numerals are supposed to be optimized for tabular display, meaning uniform, legible and evenly spaced, and proportional numerals are supposed to be a proportionate size.

Old-style numerals (onum) are what they say on the tin — those old fashioned numerals that don’t all sit on the font baseline and are not uniform height.

In the below examples, you can see the original numeral representation in the first image. In the second image, you can see the effect of proportional (pnum) and tabular numerals (tnum). And the third image shows the effect of old-style numerals (onum).

Numerals Before

tnum After

onum After

Some fonts also have special glyphs to represent the subscript and superscript required for fractions — frac is the relevant feature setting. The below shows a before and after example.

frac Before

frac After

Small caps and petite caps

Small caps and petite caps are supposed to provide a much better, calculated look for small caps than has historically been provided by the CSS font-variant: small-caps option.

p { 
    -webkit-font-feature-settings: "smcp" 1; 
    -moz-font-feature-settings: "smcp" 1; 
    -ms-font-feature-settings: "smcp" 1; 
    font-feature-settings: "smcp" 1; 
}</p>

<p>p { 
    -webkit-font-feature-settings: "pcap" 1; 
    -moz-font-feature-settings: "pcap" 1; 
    -ms-font-feature-settings: "pcap" 1; 
    font-feature-settings: "pcap" 1; 
}

smcp Before

smcp After

The above image shows small caps (smcp) applied again to Monarcha Book from Fontdeck.

Kerning

Kerning refers to the practice of adjusting the gaps between certain pairs of characters to make the gaps appear more natural and consistent with the gaps everywhere else. This tends to be an issue with letter pairings such as “Wo”, “Na”, with more angular characters. Some fonts have kerning information built in, which can be turned on and off. I’ve included an obvious example below.

p { 
    -webkit-font-feature-settings: "kern" 1; 
    -moz-font-feature-settings: "kern" 1; 
    -ms-font-feature-settings: "kern" 1; 
    font-feature-settings: "kern" 1; 
}

Kerning After

Kerning Before

This kerning example uses the Magneta Book Italic font, available from Fontdeck.

Stylistic sets and other assorted effects

Finally, I’ll look at a kind of miscellaneous bucket of effect types. You’ll find fonts that have completely different letter forms available, or swashes and letter forms that only appear in certain contexts.

p { 
    -webkit-font-feature-settings: "ss01" 1, "swsh" 1, "cswh" 1, "calt"; 
    -moz-font-feature-settings: "ss01" 1, "swsh" 1, "cswh" 1, "calt"; 
    -ms-font-feature-settings: "ss01" 1, "swsh" 1, "cswh" 1, "calt"; 
    font-feature-settings: "ss01" 1, "swsh" 1, "cswh" 1, "calt"; 
}

ss = stylistic set.
swsh = stylistic swash
cswh = contextual swash
calt = contextual alternative

There are probably others available too, which we may uncover in due course.

If we apply stylistic swashes to the Trilogy Fatface Regular font from Fontdeck:

p { 
    -webkit-font-feature-settings: "swsh" 1; 
    -moz-font-feature-settings: "swsh" 1; 
    -ms-font-feature-settings: "swsh" 1; 
    font-feature-settings: "swsh" 1; 
}

We get the following interesting effects:

Swashes Before

Swashes After

Stylistic sets are even more fun. The font Majestic Mishmash from Fontdeck contains completely different stylistic sets.

p { 
    /* standard font */ 
}

The image below represents the way the font normally looks (i.e. the “standard” look without using font-feature-settings):

Standard font

Now we’ll apply the following CSS:

p { 
    -webkit-font-feature-settings: "ss01" 1; 
    -moz-font-feature-settings: "ss01" 1; 
    -ms-font-feature-settings: "ss01" 1; 
    font-feature-settings: "ss01" 1; 
}

And the image below shows the result:

ss01

Tips for font-feature usage

To wrap things up, below are some tips for usage.

Build up test files

When deciding what fonts to use, it is a good idea to set up a test file that includes different sections of text set to be styled with all the different possible font feature settings. So you can then apply different fonts to the page (for example from Fontdeck), and see what the different open type font features look like when rendered on the page.

Use font subsets

You’ll probably not want to use advanced font features on all of your type. Most likely, you’ll just want to apply such features to headings, single characters, or small strings of characters in specific places. In many situations you could probably save some bandwidth and processing power by using small subsets of your fonts that just contain the characters you need

p { 
    font-family: 'my posh font subset'; 
    -webkit-font-feature-settings: "ss01" 1, "swsh" 1, "cswh" 1, "calt"; 
    -moz-font-feature-settings: "ss01" 1, "swsh" 1, "cswh" 1, "calt"; 
    -ms-font-feature-settings: "ss01" 1, "swsh" 1, "cswh" 1, "calt"; 
    font-feature-settings: "ss01" 1, "swsh" 1, "cswh" 1, "calt"; 
}

Conclusion

That’s it for this one. If you have any experience with these features or have anything to add, we’d love to hear your comments.