What is a variable font — one file instead of eight

Open any site and try setting font-weight: 437. With a regular font nothing happens — the browser rounds to the nearest weight it actually has on disk. With a variable font you get exactly 437. Not "almost bold", a specific point in between.
That's the whole idea: weight stopped being a choice between two files and became a slider.
Before: one file per style
A classic font works like this: one file, one combination of width, weight and slant. Regular is a file. Bold is a second file. Bold Italic is a third.
For ordinary body text on a site that's four files minimum: regular, italic, bold, bold italic. Want a light weight for captions and an extra-bold for emphasis — add a few more. MDN puts a complete typeface at 20–30 files, and every file is a separate network request, usually 20 KB or more.
And the browser doesn't invent them: in a real italic the letters are often redrawn (lowercase "a" and "g" look quite different in italics). Faking styles by slanting is a bad idea — you want honest files.
The variation axis — the core idea
A variable font packs all those options into one file. Instead of finished styles it holds variation axes — ranges along which a letter can change.
The spec defines five "registered" axes, each with a four-letter tag:
wght— weight, from thin to heavy;wdth— width, condensed or extended;slnt— slant, in degrees;ital— italic (usually not a range but a 0-or-1 switch);opsz— optical size: letters tuned for small or large type.
Beyond those, a type designer can define custom axes — say, GRAD for "more weight without changing width". There's a lovely detail in the spec here: axis names are case-sensitive, registered ones are lowercase and custom ones are UPPERCASE. Get the case wrong and the axis quietly does nothing.
What changes in your CSS
The good news: almost nothing. All five registered axes map to normal properties, so most of the time you write what you always wrote — font-weight, font-style, font-stretch.
What changes is the range. With a static font, font-weight means 100, 200, … 900, in steps of a hundred. With a variable font, as MDN says, any number from 1 to 1000 is valid. Hence font-weight: 437.
For non-standard axes there's the low-level font-variation-settings. It has one annoying quirk: if you've set several axes and want to change one, you have to re-list all of them, or the rest reset. The usual workaround is CSS variables: put var(--wght) inside font-variation-settings and change only the variable afterwards. That's also what makes the font animatable — you can drive the variable from JavaScript or on hover.
One thing variable fonts still can't do: @font-face gives you no way to say "this point on the axis is my bold". If you need a non-standard bold, set it explicitly in your rules.
How to hook it up: the detail that trips people
You load a variable font with the same @font-face as any other — with one mandatory change. The browser needs to know which weight range the file covers:
@font-face {
font-family: "MyFont";
src: url("/fonts/myfont.woff2") format("woff2");
font-weight: 100 900; /* two space-separated values — that's a range */
}
Two values separated by a space are the range. Forget it and the browser assumes the file holds a single weight, then fakes the rest itself: it draws a synthetic bold on top of the regular instead of using the real wght axis. It looks almost right, which is exactly why the mistake slips through. For a font with the full span you can write 1 1000.
You usually don't need to touch the optical axis: font-optical-sizing defaults to auto, so the browser picks the right cut for the current size — small text gets wider, more open letters, large text gets finer detail.
Is it worth it
Honest answer: count your files.
One variable file is heavier than one static file — it carries every intermediate state. But as MDN notes, it's usually smaller than or about the same as the four files you're already loading for body copy. In exchange you get the entire range instead of four fixed points.
So the win shows up when you use many styles: a heavier heading, a lighter caption, a condensed cut for mobile. If your site lives on exactly one regular weight, a variable font only adds bytes. Like any resource-loading story, it's part of a bigger picture: what else slows a site down and in what order to fix it.
Is a variable font always lighter?
No. It's lighter than a set of four or more static files, but heavier than a single one. If you use one or two styles, static files win.
Do I need font-variation-settings?
For the five registered axes, no — the spec explicitly recommends normal properties like font-weight. The low-level syntax is only for a font's custom axes.
Where do I get a variable font?
Free font catalogues usually have a dedicated filter, and file names often carry a VF or Variable marker. You load it through @font-face exactly like a regular font — just once instead of four times. Line spacing is still up to you, though: how line-height works.
Short story-lessons, an agent simulator and daily practice — in our mobile app. Free.





