Inter is the default sans-serif for a huge slice of the web — VS Code uses it, Figma ships it as a system font, and virtually every SaaS design system has a copy. Most developers install it, set font-family: 'Inter', sans-serif, and stop there. That leaves a surprising amount of typographic control untouched. Inter ships with eight stylistic sets and thirteen character variants that change how specific glyphs render, all accessible through two CSS properties. This guide shows you exactly how to use them — in vanilla CSS and in Tailwind CSS v4.
Before diving into the features themselves, it helps to understand the two CSS properties involved: font-feature-settings and the newer font-variant-* family. The short version: prefer font-variant-alternates and friends when browser support allows; use font-feature-settings as a reliable fallback or when you need fine-grained on/off control. Inter's own stylesheet now ships @font-feature-values declarations, which let you use human-readable names instead of four-letter codes.
What Inter ships with
The Inter font file (and the variable font InterVariable) includes the following OpenType features, pulled directly from the official inter.css stylesheet.
Stylistic sets (ss01–ss08)
- ss01 — open-digits: Alternative digit forms with more open apertures. Useful in data-heavy UIs where 6 and 9 can be confused with 0.
- ss02 — disambiguation: A full disambiguation set — increases visual difference between easily confused characters (
Il1,O0). Includes a slashed zero. - ss03 — round-quotes-and-commas: Curved punctuation variants for a softer feel.
- ss04 — disambiguation-except-zero: Same character disambiguation as ss02 but without the slashed zero — useful when a slashed zero looks wrong in your context.
- ss05 — circled-characters: Glyphs enclosed within circles; useful for annotation or label systems.
- ss06 — squared-characters: Glyphs enclosed within squares.
- ss07 — square-punctuation: Angular punctuation replacing the default rounded forms.
- ss08 — square-quotes: Rectangular quotation mark variants.
Character variants (cv01–cv13)
- cv01 — alt-1: Alternate numeral 1 (with a flag/serif at the top).
- cv02 — open-4: An open-top four — helpful for distinguishing 4 from 9 in numeric displays.
- cv03 — open-6: Open form of the digit 6.
- cv04 — open-9: Open form of the digit 9.
- cv05 — lc-l-with-tail: Lowercase L with a tail, preventing confusion with uppercase I.
- cv06 — simplified-u: A streamlined u without the trailing upstroke.
- cv07 — alt-double-s: Alternative German ß (Eszett) form.
- cv08 — uc-i-with-serif: Capital I with serifs, completely eliminating I/l ambiguity.
- cv09 — alt-3: Flat-top three.
- cv10 — uc-g-with-spur: Capital G with a spur.
- cv11 — single-story-a: Single-bowl lowercase a (the one that looks like a circle with a tail), matching a more humanist feel.
- cv12 — compact-lc-f: Narrower f with a shorter tail.
- cv13 — compact-lc-t: Narrower t.
The modern way: @font-feature-values and font-variant-alternates
Inter's official stylesheet ships @font-feature-values blocks for Inter, InterVariable, and InterDisplay. This lets you reference features by name rather than tag code, which is far more readable and avoids typos.
/* Inter's CSS already includes @font-feature-values. If you load
inter.css from rsms.me, these names are already registered.
If you self-host, copy the @font-feature-values block from inter.css. */
/* Enable a styleset by name */
body {
font-variant-alternates: styleset(disambiguation);
}
/* Enable individual character variants */
.mono-figures {
font-variant-alternates:
character-variant(alt-1, open-4, uc-i-with-serif);
}
/* Combine a styleset with individual overrides */
.code-like {
font-variant-alternates:
styleset(disambiguation),
character-variant(alt-1);
}
The named values map exactly to the four-letter codes: disambiguation is ss02, alt-1 is cv01, uc-i-with-serif is cv08, and so on. Using the names makes intent obvious at a glance.
The fallback way: font-feature-settings
font-feature-settings gives you direct access to every OpenType tag. It works everywhere and is the right tool when you need explicit on/off control, or when you are not loading Inter's official stylesheet.
/* Slashed-zero disambiguation — useful in serial numbers, codes, passwords */
.serial {
font-feature-settings: "ss02" 1;
}
/* Single-story a + serifed capital I — common UI preference */
.clean-ui {
font-feature-settings: "cv11" 1, "cv08" 1;
}
/* A reasonable "readability" stack for body text */
body {
font-feature-settings:
"liga" 1, /* standard ligatures (on by default, but explicit) */
"calt" 1, /* contextual alternates */
"ss02" 1, /* disambiguation */
"cv08" 1; /* capital I with serifs */
}
One important gotcha: font-feature-settings does not cascade incrementally. If you set it on a parent and then set it again on a child, the child's declaration replaces the parent's entirely — it does not merge. You must redeclare every feature you want active. This is the main reason MDN recommends the high-level font-variant-* properties when you can use them — they cascade correctly.
High-level font-variant properties for standard features
Several features Inter supports have dedicated high-level CSS properties that are universally supported and cascade properly:
/* Tabular (monospaced) numbers — critical in tables and data grids */
.data-table td {
font-variant-numeric: tabular-nums;
}
/* Old-style (lowercase) figures — good in running text */
.prose {
font-variant-numeric: oldstyle-nums;
}
/* Fractions */
.fraction {
font-variant-numeric: diagonal-fractions;
}
/* Small caps */
.label {
font-variant-caps: small-caps;
}
/* Common ligatures (fi, fl, etc.) */
p {
font-variant-ligatures: common-ligatures;
}
Setting Inter features in Tailwind CSS v4
Tailwind v4 replaced tailwind.config.js with a CSS-first @theme directive. Font families get their own CSS variable, and feature settings attach to that variable using a double-dash suffix.
/* In your main CSS file (e.g. globals.css or app.css) */
@import "tailwindcss";
@theme {
/* Define Inter as the sans-serif stack */
--font-sans: "InterVariable", "Inter", ui-sans-serif, system-ui, sans-serif;
/* Attach default feature settings to this font variable */
--font-sans--font-feature-settings: "liga" 1, "calt" 1, "ss02" 1, "cv08" 1;
/* Optional: variation settings for the variable font */
--font-sans--font-variation-settings: "opsz" 14;
}
The naming convention is --font-{name}--font-feature-settings — two dashes separate the font variable name from the property modifier. Tailwind reads this and automatically applies the feature settings whenever the font-sans utility class is used. You get consistent typography with no manual font-feature-settings declarations scattered through your components.
Per-component overrides with Tailwind arbitrary values
For one-off overrides, Tailwind's arbitrary value syntax works fine:
<!-- A table that needs tabular numbers -->
<td class="[font-variant-numeric:tabular-nums]">1,204</td>
<!-- A heading that uses Inter's single-story a -->
<h2 class="[font-feature-settings:'cv11'_1,'cv08'_1]">
Get started
</h2>
Note the underscore syntax: Tailwind converts underscores to spaces inside arbitrary value brackets, so 'ss02'_1 becomes 'ss02' 1 in the output CSS.
A practical starting configuration
Here is a reasonable baseline that works for most UI projects using Inter. It enables disambiguation, contextual alternates, standard ligatures, and serifed capital I — four changes that improve legibility without altering the overall character of the typeface:
/* Plain CSS approach */
:root {
--inter-features: "liga" 1, "calt" 1, "ss02" 1, "cv08" 1;
}
body {
font-family: "InterVariable", "Inter", sans-serif;
font-feature-settings: var(--inter-features);
}
/* Monospace-number contexts (tables, code, prices) */
.tabular {
font-variant-numeric: tabular-nums;
}
/* Serial numbers, passwords, API keys */
.code-string {
font-feature-settings: "ss02" 1, "cv01" 1, "cv08" 1;
letter-spacing: 0.02em;
}
/* Tailwind v4 equivalent in @theme */
@theme {
--font-sans: "InterVariable", "Inter", ui-sans-serif, system-ui, sans-serif;
--font-sans--font-feature-settings: "liga" 1, "calt" 1, "ss02" 1, "cv08" 1;
}
Which features are worth enabling
Not every feature suits every context. A few practical notes:
- ss02 (disambiguation) is almost always worth enabling on any interface where users read codes, IDs, or serial numbers — the slashed zero alone prevents real mistakes.
- cv08 (capital I with serifs) pairs naturally with ss02 and makes the font look more deliberate in headings and UI labels.
- cv11 (single-story a) gives Inter a softer, more humanist feel — great for marketing copy, less useful for data-dense dashboards where the double-story a is more familiar.
- tabular-nums (via
font-variant-numeric) belongs on every table, price display, and stat card. It ensures digit columns stay aligned regardless of which digit appears. - The circled and squared character sets (ss05, ss06) are niche — think annotation systems or badge-style labels — and should be scoped to specific components rather than applied globally.
Loading Inter with font-feature support
If you load Inter from Google Fonts, note that the Google Fonts API does support OpenType features for Inter — your CSS declarations will work. If you self-host, download the variable font (InterVariable.woff2) from the rsms/inter GitHub repository and copy the @font-face and @font-feature-values blocks from inter.css. The variable font is a single file that supports the full weight and optical size range, plus all the feature sets described here.
OpenType features are one of those details that most users never consciously notice — but that is exactly the point. A slashed zero in an API key field, tabular numbers in a pricing table, a serifed capital I in a navigation label — these small choices accumulate into a UI that feels considered and precise. Inter gives you all of this for free; you just have to turn it on.