OpenType Features in CSS

I’ve been playing a little with Open Type font variations (and their CSS equivalents) for a few weeks now and I’ve revisited a few areas I had played with before and left because, at the time, I didn’t see the need or usefulness.

That said, there are projects where good typography is just as important than size, line height, and other basic elements. In this essay, we’ll look at some less common features of OpenType fonts and how to use them in CSS, both the original specification using font-feature-settings and the newer version using font-variants-*. We’ll also look at ways to DRY our code and keep ourselves from repeating code.

CSS Fonts Module Level 3 defines the set of OpenType features supported by spec-compliant browsers

Older browsers may support a font-feature-settings, a lower level syntax to control access to the OpenType features.

To cover all our bases we’d have to do something like this:

.liga {
  @supports not (font-variant-ligatures: common-ligatures) {
    font-feature-settings: "liga";
  }

  /* IE doesn’t support @supports; explicitly use the prefixed version. */
  -ms-font-feature-settings: "liga";

  /* Best case scenario, just use `font-variant-*`. */
  font-variant-ligatures: common-ligatures;
}

We test if the browser does not support font feature settings. If it doesn’t we fall back to font feature settings for ligatures.

Because neither Edge nor IE supports the @supports command. Because of this we need to add the Microsoft specific

The final case uses font-variant-ligatures.

A more elegant, and effortless, solution is to use the Utility OpenType library from Kenneth Normandy that takes a slightly different approach to using the different supported way of doing things.

It sets up the default values and then tests if either the webkit- or the regular value for font-variant-ligatures are not supported and if the tests fail (meaning they are supported) it changes the support to use font-feature-settings and the webkit prefixed version.

.liga {
  -ms-font-feature-settings: "liga";
  -webkit-font-variant-ligatures: common-ligatures;
          font-variant-ligatures: common-ligatures;
}

@supports not ((-webkit-font-variant-ligatures: common-ligatures) or
              (font-variant-ligatures: common-ligatures)) {
  .liga {
    -webkit-font-feature-settings: "liga", "liga", "clig";
    font-feature-settings: "liga", "liga", "clig";
  }
}

Using this in combination with variable fonts that support the OpenType features we need gives us a lot of flexibility when it comes to typography.

Links and Resources