font-variant-alternates

Juan Diego Rodríguez on

Get affordable and hassle-free WordPress hosting plans with Cloudways — start your free trial today.

The CSS font-variant-alternates property lets you apply font features picked by the @font-feature-values at-rule, such as style sets, ornaments, and swashes. Font features are font-specific, so font-variant-alternates lets the browser know the correct feature to apply depending on the font-family.

@font-feature-values Skrine {
  @styleset {
    pigtail: 4; /* Sets ss04 on */
  }
}

h1 {
  font-family: Skrine;
  font-variant-alternates: styleset(pigtail);
}

The font-variant-alternates property is defined in the CSS Fonts Module Level 4 specification.

Syntax

font-variant-alternates: normal | [ stylistic(<feature-value-name>) || historical-forms || styleset(<feature-value-name>#) || character-variant(<feature-value-name>#) || swash(<feature-value-name>) || ornaments(<feature-value-name>) || annotation(<feature-value-name>) ]

<feature-value-name> = <ident>
  • Initial: normal
  • Applies to: all elements and text
  • Inherited: yes
  • Percentages: N/a
  • Computed value: specified keyword
  • Canonical order: per grammar
  • Animation type: discrete

Values

font-variant-alternates: historical-forms;
font-variant-alternates: stylistic(tails);
font-variant-alternates: styleset(fancy);
font-variant-alternates: character-variant(g-foot);
font-variant-alternates: swash(fancy);
font-variant-alternates: ornaments(a-fleuron);
font-variant-alternates: annotation(circled-black);
  • normal: No feature is enabled.
  • historical-forms: Enables historical forms, which match OpenType hist feature tag.
  • stylistic(): Enables stylistic alternates, which match the OpenType salt feature tag.
  • styleset(): Enables stylistic sets, which match the OpenType ss01 to ss20 feature tag.
  • character-variant(): Enables specific character variants, which match the OpenType cv01 to cv99 feature tag.
  • swash(): Enables swash glyphs, which match the OpenType swsh feature tag.
  • ornaments(): Enables default glyphs with ornaments, which match the OpenType ornm feature tag.
  • annotation(): Enables alternate annotation forms, which match the OpenType nalt feature tag.

Many font features!

You can think of @font-feature-values and this entry as sister entries, so if you want to get a better picture of font features and why we need font-variant-alternates, then I encourage you to check it. In the @font-feature-values entry, we talked about OpenType fonts — a font format with many improvements, but whose main appeal was the ability to save different glyphs of the same character for different situations.

Different Alternates for the letter "A"

An OpenType font could have alternates for kerningligaturesswashes, and many other variants that can be picked by the font user. These variations on the same font are called font features.

There are many ways to set font features: some have their own property (such as font-kerning), but many can only be changed manually. In the @font-feature-values entry, we concluded that the best way to set those features was to define them through  @font-feature-values and then apply them through the font-variant-alternates property.

However, we didn’t mention exactly what each font feature did but rather focused more on the syntax to set them. This time, we will look over each of the available font features in @font-feature-values/font-variant-alternates and what they do. Although we need to first recap their basic usage.

Basic usage

First, we will need an OpenType font with some font features to play with. I’ll be using Skrine by Gianstudio. We can know exactly which features are available in a font using the Wakamai Fondue tool, which returns us the following features:

Skrine Available Features

Scrolling down, we’ll see a breakdown of each available font feature. In this case, I liked how the ss06 (Stylistic Set 06) feature gave the font a fancy look:

Skrine Stylistic Set 06 Feature

We can give that specific feature a common name using the @font-feature-values at-rule. Since it’s a stylistic set feature, we’ll need the @styleset rule. Inside, we give it any name followed by the index of the feature we want to turn on:

@font-feature-values Skrine {
  @styleset {
    fancy: 6; /* Enables feature ss06 */
  }
}

And to apply it to an element, we will use the font-variant-alternates property. It takes a wrapper function with the same name as the rule we used (styleset()) and the feature name as an argument.

h1 {
  font-family: Skrine;
  font-variant-alternates: styleset(fancy);
}

However, styleset() is just one of the many features we can use inside font-variant-alternates.

historical-forms

In the past, some letters had a different form than what they are today. The most known example is the Long s ⟨ſ⟩: an archaic version of the lowercase letter “s” which looks like a modern “f“. For that reason, some fonts have variable glyphs for historical letter forms (equivalent to the hist feature tag), which can be enabled through the historical-forms value.

h1 {
  font-family: "Sorts Mill Goudy";
  font-variant-alternates: historical-forms;
}

Notice how, unlike the following values, historical-forms is a keyword and not a wrapper function, meaning it doesn’t have a useful equivalent rule in @font-feature-values.

stylistic()

Stylistic alternates (equivalent to the salt feature tag), are glyphs variations with an entirely stylistic purpose. This feature replaces the default forms with stylistic alternates.

@font-feature-values Melody {
  @stylistic {
    tails: 1; /* Sets salt to 1 */
  }
}

h1 {
  font-family: "Melody";
  font-variant-alternates: stylistic(tails);
}

styleset()

While stylistic alternates usually affect all characters, some fonts have glyph variations that only affect a set of characters, hence the feature name stylistic set (equivalent to the ssXX feature tag). Individual stylistic sets are named ssXX, in which XX refers to the set index and goes from ss01 to ss20.

@font-feature-values Skrine {
  @styleset {
    fronttail: 1; /* Sets ss01 */
  }
}

h1 {
  font-family: "Skrine";
  font-variant-alternates: styleset(fronttail);
}

character-variant()

Both stylistic alternates and stylistic sets apply to large sets of characters, so to apply a glyph variation for a specific character we will need to use the character variant (equivalent to the cvXX feature tag) feature. Individual character variants are named cvXX, in which XX refers to the variant index and goes from cv01 to cv99.

@font-feature-values Inter {
  @character-variant {
    g-foot: 10; /* Sets cv10 */
  }
}

h1 {
  font-family: "Inter";
  font-variant-alternates: character-variant(g-foot);
}

swash()

Swash symbols (equivalent to the swsh feature tag), are glyphs with exaggerated details such as long serifs or tails. This feature replaces the default form with its swash versions.

@font-feature-values Bickham Script {
  @swash {
    fancy: 1; /* Sets swsh to 1 */
  }
}

h1 {
  font-family: "Bickham Script";
  font-variant-alternates: swash(fancy);
}

ornaments()

Ornaments (equivalent to the ornm feature tag) are glyphs used purely for aesthetic purposes. Unlike stylistic alternates, ornaments don’t have a semantic meaning and aren’t linked to any character. Per OpenType spec, we can replace the bullet character with an ornament or replace specific “lower ASCII” characters.

@font-feature-values Anggrelli {
  @ornaments {
    a-fleuron: 1; /* Sets ornm to 1 */
  }
}

h1 {
  font-family: "Anggrelli";
  font-variant-alternates: ornaments(a-fleuron);
}

annotation()

Annotations (equivalent to the nalt feature tag) refer to the different ways numbers can be displayed, usually as glyphs placed in open or solid circles, squares, parentheses, diamonds, or rounded boxes. This feature replaces the default number form with its annotation versions.

@font-feature-values Gothic A1 {
  @annotation {
    a-fleuron: 6; /* Sets nalt to 6 */
  }
}

h1 {
  font-family: "Gothic A1";
  font-variant-alternates: annotation(a-fleuron);
}

Specification

The font-variant-alternates property is defined in the CSS Fonts Module Level 4 specification, which is currently in Editor’s Draft.

Browser support

Both the @font-feature-values and the font-variant-alternates are supported on all browsers.

More information