CSS Portal

@font-feature-values CSS At-Rule

If this site has been useful, we’d love your support! Consider buying us a coffee to keep things going strong!

Description

The @font-feature-values at-rule provides a way for authors and type designers to give human‑friendly names to OpenType font features and alternative glyph selections. Instead of relying solely on cryptic feature tags (like ss01 or cv04) or low‑level feature settings, designers can expose readable feature names that map to one or more underlying OpenType features. This makes it easier for stylesheet authors to describe typographic intent (for example, “titling” or “old‑style numerals”) without needing to remember or expose the raw feature tags used by a specific font.

Because the mappings live in the stylesheet, the at‑rule acts as a bridge between a font’s implementation details and the rest of your CSS. You can define a set of feature aliases that reflect the capabilities of a particular font family and then enable those aliases elsewhere in your styles using the higher‑level typographic properties. If a font does not implement the underlying features named by an alias, the alias simply has no visual effect, so these definitions are best thought of as a convenience and documentation mechanism rather than a guarantee of rendering across different fonts.

In practical use this at‑rule is especially valuable for rich typographic systems and design systems. Type foundries can publish CSS that documents and exposes a font’s custom stylistic sets, swashes, or character variants; designers can then toggle those named features in their components without needing to understand the font’s internal tags. For web developers, this reduces cognitive load and makes collaborative work simpler: developers can apply semantically meaningful typographic tweaks (for instance, “use small caps” or “enable discretionary ligatures”) in a consistent way across a site or product.

When authoring and maintaining font feature value mappings, it’s good practice to choose clear, stable, and descriptive names, document which font families they apply to, and avoid using them to communicate essential content (since they may not be honored by all fonts or user agents). Treat these mappings as progressive enhancement for typography: they improve appearance where supported but should not be relied upon for accessibility or core legibility. Finally, because they describe font‑specific capabilities, keep in mind that aliases are only as portable as the fonts you pair them with — if you switch fonts, you should review or update the mappings so they still reflect the new font’s available features.

Syntax

@font-feature-values <family-name># {
  <feature-value-block-list>
}
where 
<family-name> = <string> | <custom-ident>+
<feature-value-block-list> = <feature-value-block>+

where 
<feature-value-block> = <feature-type> '{' <feature-value-declaration-list> '}'

where 
<feature-type> = @stylistic | @historical-forms | @styleset | @character-variant | @swash | @ornaments | @annotation
<feature-value-declaration-list> = <feature-value-declaration>

where 
<feature-value-declaration> = <custom-ident>: <integer>+;

Values

  • @swashSets the name of the function that will work with the function notation swash() for font-variant-alternates. A function value definition swash allows only one value: ident1: 2 is valid, but ident2: 2 4 is not.
  • @annotationSets the name of the function that will work with the function notation annotation() for font-variant-alternates. A function value definition allows only one value: ident1: 2 is valid, but ident2: 2 4 is not.
  • @ornamentsSets the name of the function that will work with the function notation ornaments() for font-variant-alternates. A function value definition ornaments allows only one value: ident1: 2 is valid, but ident2: 2 4 is not.
  • @stylisticSpecifies the name of the function that will work with functional notation stylistic() font-option-alternates. The definition of the value of a stylistic feature allows only one meaning: ident1: 2 is valid, but identif2: 2 4 is not.
  • @stylesetSpecifies the name of the function that will work with functional notation styleset() font-option-alternates. The stylet function value definition allows an unlimited number of values: identif1: 2 4 12 1 maps to the OpenType values ss02​​, ss04, ss12 and ss01. Note that values ​​above 99 are valid but do not map to any OpenType values ​​and are ignored.
  • @character-variantSpecifies the name of the function that will work with functional notation character-variant() font-variant-alternates. The characteristic value definition in the symbolic variant allows one or two values: ident1: 3 maps to cv03 = 1, and ident2: 2 4 maps to cv02 = 4, but ident2: 2 4 5 is not allowed.

Example

/* At-rule for "nice-style" in Font One */
@font-feature-values Font One {
@styleset {
nice-style: 12;
}
}

/* At-rule for "nice-style" in Font Two */
@font-feature-values Font Two {
@styleset {
nice-style: 4;
}
}

/* Apply the at-rules with a single declaration */
.nice-look {
font-variant-alternates: styleset(nice-style);
}

Browser Support

The following information will show you the current browser support for the CSS at-rule @font-feature-values. Hover over a browser icon to see the version that first introduced support for this CSS at-rule.

This at-rule is supported in some modern browsers, but not all.
Desktop
Chrome
Edge
Firefox
Opera
Safari
Tablets & Mobile
Chrome Android
Firefox Android
Opera Android
Safari iOS
Samsung Internet
Android WebView
-

Last updated by CSSPortal on: 28th December 2025

If this site has been useful, we’d love your support! Consider buying us a coffee to keep things going strong!