Utility OpenType

Simple, CSS utility classes for advanced typographic features. Falls back gracefully through feature queries. Less than 1.75kB gzipped. @kennethormandy

Utility OpenType helps you make the most of the font that you are loading in, reducing convoluted CSS into four-letter, typographic utility classes, because:

  1. OpenType features should be as easy to apply as bold and italics.
  2. OpenType features should cascade predictably.
  3. OpenType features should fallback gracefully.

This is described in more detail in the design decisions. The following examples are supported on Chrome, Firefox, and Internet Explorer 10+ and fallback elsewhere. Works on its own, or alongside frameworks like Basscss.

Get started Star on GitHub for later

Common ligatures

Ligatures can help solve problems with space in a typeface, especially where collisions might otherwise occur:

Difficultés de film
Difficultés de film
<span class="liga">Difficultés de film</span>

Most common ligatures mitigate spacing issues between specific combinations of letters within a typeface, often by connecting glyphs that might otherwise collide. The most cited example of this occurs between the f and itself, or another letter like i. Here, the f f i are turned into an ffi ligature, where the glyphs would awkwardly overlap otherwise.

Ligatures may also be included in a font to add character to a typeface, differentiate it, or to make a script font more convincing.


OpenType features are applied in CSS using either the High-level font-feature-settings property, or a low level font-variant-* property. The former has better browser support, while the latter avoids maintainability issues by only influencing the one property you actually want to change. This library takes care of applying the correct property, based on the browser’s ability to support font-variant-*

Using the .liga as an example:

.liga {

  /* Gracefully degrade to `font-feature-settings` to
   * avoid disrupting the OpenType feature cascade
   * when possible. */
  @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;

Discretionary ligatures

Discretionary ligatures’ defining characteristic is that they are available to enable at your discretion: they are disabled by default. Often, these are additional ligatures that might be considered too attention-grabbing or unconventional to be enabled in many situations:

The suboctave stalemate
The suboctave stalemate
<span class="dlig">Suboctave stalemate</span>

Other typefaces approach this entirely differently, offering up different number styles when wrapping numbers in brackets, like the typeface Echo from Typotheque.

Small Caps

Small Caps are less distracting than all capitals for longer form text settings. They also provide an additional way to apply emphasis within text:

icu I​C​U Icu
icu I​C​U Icu
<span class="smcp">icu ICU Icu</span>

Matthew Butterick’s Practical Typography includes a very informative section on small caps. As he points out:

Don’t click on the small-cap for­mat­ting box in your word proces­sor. Ever. And don’t use the CSS prop­erty font-vari­ant: small-caps. Ever. These op­tions do not pro­duce small caps. They pro­duce in­fe­rior counterfeits.

Instead, Utility OpenType uses the more recent font-variant-caps: small-caps feature:

.smcp {
  /* For browsers that don’t support OpenType,
  * features, use all caps. */
  text-transform: uppercase;

  /* Progressively enhance with `font-feature-settings`
  * if `font-variant-caps` isn’t supported. */
  @supports not (font-variant-caps: small-caps) {
    text-transform: inherit;
    font-feature-settings: "lnum", "smcp", "c2sc" 0;

  /* Otherwise, and ideally, use `font-variant-caps`. */
  @supports (font-variant-caps: small-caps) {
    text-transform: inherit;
    font-variant-caps: small-caps;

Caps to Small Caps

The Caps to Small Caps OpenType feature will convert all letters, not just lowercase letters, into Small Caps:

icu I​C​U Icu
icu I​C​U Icu
<span class="c2sc">icu ICU Icu</span>

Case sensitive forms

Case Sensitive Forms are alternate glyphs that are specifically designed to work alongside all caps settings, or alongside text:

¿¡№25 @K​E​N​N​E​T​H​O​R​M​A​N​D​Y!?
¿¡№25 @K​E​N​N​E​T​H​O​R​M​A​N​D​Y!?
<span class="case">¿¡№25 @K​E​N​N​E​T​H​O​R​M​A​N​D​Y!?</span>

Today, we inject @-mentions, add #hashtags, and prefix text with symbols in our writing, more often than ever; Case Sensitive Forms in fonts can help you cohesively typeset this information.

In well-formed fonts, the lowercase forms should be set as the defaults, with the all-caps or lining variations available on the Case Sensitive Forms feature. This feature (and CSS class) also overrides any number styles set, turning Oldstyle Numbers into Lining Numbers.

Titling alternates

Titling Alternates provide alternates ready for display settings. In this example, Lavanderia’s titling caps provide a different tone, and let it work in additional headline settings:

Sign Painters Rule
Sign Painters Rule
<span class="titl">Sign Painters Rule</span>

Contextual alternates

Contextual alternates are particularly important for fonts that intend to mimic lettering, whether they are scripts or stencils like Shiva Nallaperumal’s Enemy:

<span class="calt">Bookkeepers</span>

For this font, glyphs alternate to create a more convincing stencil pattern. Other fonts, particularly script fonts, take advantage of this OpenType feature differently.

The OpenType specification defines this feature, like Ligatures, as a required default, so browsers should have it on already. In practice, this is not always the case, so you can also enable it with the Utility OpenType .calt class.

Stylistic alternates

Sometimes the a significant portion of a typeface’s unique character comes from a few specific glyphs. Stylistic Alternates offer an opportunity to change these, and change the tone of the typeface. In this example, Proxima Nova’s Stylistic Alternates are use to change to a more distinctive l and a single storey a, with the G and y following suit:

<span class="salt">Glastonbury</span>

Every other glyph in this particular typeface would remain the same. Depending on the typeface you are using, Stylistic Alternates might provide a different outcome. For example, with the typeface Lavanderia,

Stylistic alternates provide simpler forms (no loops on top) for the lowercase b, h, f, l, and k. Simpler forms can work better in certain situations.

For this particular typeface, the result of using the .salt class is:

<span class="salt">bookshelf</span>

Historical alternates

Historical glyph variants aren’t likely to be useful in everyday most typesetting situations, but may prove useful when trying to reference the past:

<span class="hist">Blasphemous</span>

The most common example of this is the long s, shown in this example.


Swashes add additional flare to a typeface, and are usually best applied conservatively:

Notably Yours
Notably Yours
No<span class="swsh">t</span>abl<span class="swsh">y Yours</span>

With the .swsh utility class, you can apply Swashes only to the letters you need. Applying them to a heading in its entirety can have an unintentionally uncontrolled look:

Notably Yours
Notably Yours
Notabl<span class="swsh">y Yours</span>

Proportional, Oldstyle numbers

There are situations where different kinds of number styles are useful based on the kind of information you are trying to typeset. Not all typefaces contain all number styles, but if they are availably, these helper classes will use them. Oldstyle, proportional numbers are often the default in typefaces intended for setting long-form text, especially serifs:

0123456789 $10 £20 ¥30 40% 50‰
<span class="pnum onum">0123456789 $10 £20 ¥30 40% 50‰</span>

Proportional numbers are designed to take up whatever width they need. Old style numbers, .onum, are designed to sit alongside the lowercase letters, so they are less distracting within text.

Proportional, Lining numbers

Tabular numerals are monospaced, so different information can be easily compared when stacked vertically:

0123456789 $10 £20 ¥30 40% 50‰
0123456789 $10 £20 ¥30 40% 50‰
<span class="pnum lnum">0123456789 $10 £20 ¥30 40% 50‰</span>

Tabular, Lining numbers

0123456789 $10 £20 ¥30 40% 50‰
0123456789 $10 £20 ¥30 40% 50‰
<span class="tnum lnum">0123456789 $10 £20 ¥30 40% 50‰</span>

Tabular, Oldstyle numbers

0123456789 $10 £20 ¥30 40% 50‰
0123456789 $10 £20 ¥30 40% 50‰
<span class="tnum onum">0123456789 $10 £20 ¥30 40% 50‰</span>

Diagonal fractions

This feature is very useful when working with basic fractions: just write your fractions in plain text, as you might anyway—1​/​10—and they will automatically be assembled into optically corrected numerators and denominators, properly spaced as fractions—1/10—in fonts that support this OpenType feature:

1/2 1/4 1/100
1/2 1/4 1/100
<span class="frac">1/2 1/4 1/100</span>

Some fonts include a second, stacked fraction style. This is accessible through an .afrc class.


Ordinals usually follow numbers. A typeface might include specific glpyh combinations for 1st or 2nd. There also might be ordinals available for different languages, like Italian:

La 2a pagina
La 2a pagina
La <span class="ordn">2a</span> pagina


Test1 with .subs only
Test1 with sub only
Test1 with sub and .subs
H<sub class="subs">2</sub>O


Test1 with .sups only
Test1 with sup only
Test1 with sup and .sups
H<sup class="sups">2</sup>O

Scientific Inferiors

Scientific Inferior are for chemical and mathematical typesetting, and include optically corrected letters and numbers:

H<sub class="sinf">2</sub>O

The second, greyed out example shown here shows the faux subscripts the browser creates by scaling whatever you put in the H<sub> tag; by using the sinf class from Utility OpenType instead, you’ll use the optically correct glyphs included in your web font. In browsers that don’t support the OpenType features, the browser default will still be used.

Slashed Zero

To distinguish the zero from the letter O, some fonts include an alternate, slashed zero glyph. This can be useful in various inputs, like credit card forms, and when displaying data in tables.

$1,000 Over
$1,000 Over
<span class="zero">$1,000 Over</span>

Slashed, Oldstyle Zero

You may also combine the .zero class with .tnum, .onum, .lnum, or .pnum. If the font includes those glyphs—like the additional Oldstyle Zero in the following example, it will be used instead:

$0.01 owed
$0.01 owed
<span class="zero onum">$0.01 Owed</span>

Feature requests

Think something is missing? Submit an issue or feature request on GitHub and let’s talk about it!

Design decisions

Following the ideas established in Basscss, utility classes should

…provide the backbone for typography and layout and, once set, should never be changed or extended. Each utility should contain as few CSS properties as possible, generally just one or two. Utilities should do one thing and do it well, they should be simple and obvious to use, and they should operate independently.

This library should work well alongside Basscss or any declarative CSS framework. The classes are design with the idea that:

  1. OpenType features should be as easy to apply as bold and italics.

    Utility OpenType provides concise, declarative classes that you can easily apply to entire elements, or specifically scope to inline spans when you are working on fine typographic details like discretionary ligatures. They are intended to be immutable and don’t interfere or concern themselves with any other part of your CSS.

  2. OpenType features should cascade predictably.

    The font-feature-settings property is often used to apply these advanced typographic features, because it has significantly better browser support than its lower-level, font-variant-* counterpart. Unfortunately, it doesn’t always carry down one feature to the next; imagine only being able to use the margin or font property in CSS, but not margin-left or font-size and you’ll begin to see the maintainability problems this can cause.

    You can read more about this problem in my article on normalising OpenType feature defaults, and on Typekit Practice—or, skip both: Utility OpenType mitigates this problem through CSS @supports feature queries.

  3. OpenType features should fallback gracefully.

    Provide a better experience for Chrome, Firefox, and Internet Explorer 10+ (yes, seriously) without negatively impacting the rest: Small Caps are progressively enhanced from text-transform: uppercase, and Scientific Inferiors maintain the browser default <sub> styling so your H2O never says H2O.


Utility OpenType is ready to use with Sass, PostCSS, or vanilla CSS. If you’re using Sass or PostCSS, install it through npm:

npm install --save utility-opentype

Then, include it within your source files:

@import "utility-opentype";

If you’re using Sass without Eyeglass modules, you will need to include the actual path to the file in the node_modules directory, for example:

@import "../node_modules/utility-opentype/css/utility-opentype";

If you’d like to use the CSS directly, download the latest version of the compiled file, or reference the hosted CDN version in your HTML:

<link href="https://cdn.rawgit.com/kennethormandy/utility-opentype/master/css/utility-opentype.min.css" rel="stylesheet">

That’s it! You’re ready to use the classes within your markup.


OpenType features don’t alter the underlying text: spelling, the ability to copy-and-paste, interactive features like searching within a page or editing text, and accessibility considerations like compatibility with screen readers, are not impacted.

Browser support

The example shown are fully supported in Chrome, Firefox, and Internet Explorer 10+. Safari 6+ and Safari 6+ on iOS only support Common Ligatures and Contextual Alternates, and only as a browser default; they cannot be disabled via CSS.

All features use a combination of progressive enhancement and graceful degradation—primarily through @supports CSS feature queries—to mitigate problems on browsers and devices where advanced typography features aren’t supported.