Variable fonts

Variable fonts

Last updated 2026-11-02

  • 变量字体
  • 可变字体
  • variable font
  • 轴
  • 光学尺寸
  • opsz
On this page

A static family is "one file per weight". A variable font replaces that with "one file containing a continuous axis". That changes the design workflow more than it sounds: it changes what a "weight" even is.

Axes and named instances

An axis is a dimension with a minimum, a default and a maximum. The usual ones:

Axis Meaning Typical range
wght Weight 100–900
wdth Width 75–125 (percent)
opsz Optical size 8–144
slnt Slant −10–0 (degrees)
ital Italic 0–1

A named instance is a combination of axis positions with a name (Regular, Bold, Display). The style list in design software is usually these instances.

Crucially, instances are presets, not the whole space. Any position in the file can technically be used.

Optical size is the axis worth understanding

opsz is not "scale up or down"; it is a separate design for a different size:

  • small sizes: thicker strokes, wider spacing, fuller frames, or the text smears;
  • large sizes: thinner strokes, tighter spacing, more detail, or it looks clunky.

Traditionally this was done with two static families (Text / Display); a variable font turns it into one continuous axis. So opsz=12 and opsz=72 are not scaled copies — the stroke proportions change.

One CSS property makes it follow the font size:

h1 {
  font-optical-sizing: auto;
}

The browser picks opsz from the current font-size.

How to hand off

With a variable font, "specify a weight" has three possible spellings, and handoff must pick one:

  1. Named instance: "SemiBold" — safest, because the name travels with the file;
  2. Number: font-weight: 600, matched by CSS;
  3. Axis coordinate: font-variation-settings: "wght" 600 — most precise, least portable.

Recommendation: use named instances for body and UI, and axis coordinates only when you genuinely need a value between instances ("a touch lighter than SemiBold") — with a note on the layout saying why.

Where it goes wrong

  • In-between positions are not necessarily good — designers check a handful of positions; wght: 437 is interpolation;
  • PDF export / image export: some tools instantiate variable fonts into static outlines; if the instance is wrong, output differs from screen;
  • Chinese variable fonts are rare — the glyph count makes continuous axes expensive, so far fewer exist than in Latin;
  • font-variation-settings overrides font-weight — when both are present the axis coordinate wins, which is hard to debug.

How this site records it

Conservatively: one file is one entry, recording default weight and width only. Axes are not expanded into faces.

Because a "face" here is the identity used by favourites and archives, and a variable font's "face" is not a discrete object. Trying positions on an axis belongs to the type tester.

Further reading