A brief history of variable fonts

Variable fonts were introduced by Microsoft, Google, Apple, and Adobe in September 2016 as part of OpenType 1.8. Before this, a font family with 6 weights required 6 separate files (or 12 with italic variants). Each file stored the complete glyph data for its specific weight — but the differences between weights are often a small set of numeric deltas, not entirely different glyph outlines.

Variable fonts exploit this redundancy. The base glyph outlines are stored once, and the deltas for weight, width, slant, and other axes are stored as variations. The result is one file that can interpolate any point between the defined axes.

How variable fonts work

A variable font contains three additional tables beyond a static font:

  • fvar — defines the axes of variation: which axes exist, their minimum value, maximum value, and default value
  • gvar — stores the per-glyph deltas that describe how each glyph changes across axes
  • avar (optional) — remaps the axis values to non-linear interpolation, so designers can adjust the perceptual shape of the axis

At render time, the browser reads the CSS values for each axis, interpolates the glyph outlines, and draws the resulting shape. This interpolation is fast — the rendering cost is negligible compared to network savings.

Standard variable font axes

Axis nameTagTypical rangeCSS property
Weightwght100–900font-weight
Widthwdth50%–200%font-stretch
Italicital0 or 1font-style: italic
Slantslnt-90° to 90°font-style: oblique
Optical sizeopsz8–144ptfont-optical-sizing
GradeGRAD-200 to 150No high-level property

Custom axes are also allowed (for example, SOFT and WONK in Fraunces). By convention, custom axes use uppercase tags. You access them via font-variation-settings because they have no dedicated CSS property.

A complete example

Here is a complete variable font setup using Inter Variable at 100–900 weight:

@font-face {
  font-family: "Inter";
  src: url("/fonts/inter-var.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

body {
  font-family: "Inter", system-ui, sans-serif;
  font-weight: 400;
}

h1 {
  font-weight: 800;
}

.btn-cta {
  font-weight: 600;
}

.caption {
  font-weight: 300;
}

Every CSS font-weight value between 100 and 900 works with a single font file. The browser interpolates the outlines on the fly, and only one network request is made.

Compare the cost: Serving Inter as 6 static weights (100, 300, 400, 500, 700, 900) requires 6 WOFF2 files totaling roughly 600 KB. Serving Inter Variable at 100–900 requires one file of roughly 103 KB. Same visual result, 83% smaller.

Using font-variation-settings

For axes without a high-level CSS property (custom axes, or when you need precise control), use font-variation-settings:

.decorative {
  font-family: "Fraunces", serif;
  font-variation-settings:
    "wght" 400,
    "SOFT" 100,
    "WONK" 1;
}

For the standard axes, prefer the high-level properties — they are more performant, better supported, and correctly inherited:

  • Use font-weight instead of "wght"
  • Use font-stretch instead of "wdth"
  • Use font-style: italic instead of "ital"
  • Use font-optical-sizing: auto for "opsz"

Only use font-variation-settings for custom axes or when you must animate a specific value.

Browser support

Variable fonts are supported by:

  • Chrome 62+ (October 2017)
  • Firefox 62+ (September 2018)
  • Safari 11+ (September 2017)
  • Edge 17+ (April 2018)
  • iOS Safari 11+
  • Android Chrome 62+

In practice, this means every browser released after 2018 supports variable fonts. Support is universal for modern audiences.

Performance: the real numbers

File size depends on the font and how many axes it defines. A rough guideline for the WOFF2 format:

  • Variable font with weight axis only (100–900): 100–200 KB
  • Variable font with weight + width + italic: 200–350 KB
  • Variable font with optical size axis: slightly larger than static due to additional deltas

Compare to a static font family:

  • 6 static weights (100, 300, 400, 500, 700, 900): 6 files × 80 KB ≈ 480 KB
  • 9 static weights + italics: 15 files × 80 KB ≈ 1200 KB

For any project that needs 3+ weights, the variable font wins on file size. For a project using only one weight, a single static file may be slightly smaller — but the difference is small and the flexibility is worth it.

Tradeoffs and when not to use variable fonts

Variable fonts are not universally better in every situation:

  • Single-weight projects — if you only ever use one weight, a static file is often smaller. But the difference is rarely large enough to matter, and future flexibility has value.
  • Very complex variable fonts — some variable fonts with 3+ axes exceed 400 KB, which can be larger than a subset of static weights. Check file size before committing.
  • Older browsers — if you still support browsers before 2018, static files are necessary. This is rare in 2025.
  • Subsetting complexity — subsetting a variable font removes deltas for removed glyphs, but the process is more complex than subsetting a static font. Tools like pyftsubset handle variable fonts but require care.

Tools for working with variable fonts

OmniFonts provides several tools for variable fonts:

Frequently asked questions

What is a variable font?

A variable font is a single font file that contains multiple weights, widths, or styles controlled by CSS. Instead of loading separate static files, one variable file covers the entire axis range.

Are variable fonts smaller than static fonts?

One variable font file is smaller than 4+ static files combined. A variable font covering 100–900 weight in WOFF2 is typically 100–200 KB. The equivalent 9 static WOFF2 files total 700–1500 KB.

What are the standard variable font axes?

The registered axes are wght (weight), wdth (width), ital (italic), slnt (slant), opsz (optical size), and GRAD (grade). Custom axes are allowed using uppercase tags.

How do I use a variable font in CSS?

Declare it in @font-face with a weight range (font-weight: 100 900), then use font-weight anywhere in your CSS. For custom axes, use font-variation-settings.

Do all browsers support variable fonts?

Yes. Variable fonts are supported in Chrome 62+, Firefox 62+, Safari 11+, and Edge 17+ — every browser released after 2018.

Does using a variable font hurt rendering performance?

No. Modern browsers interpolate variable font axes with negligible performance cost. The network savings from loading one file instead of many are much larger than any rendering overhead.