
What Are Variable Fonts, and Why Should You Use Them?
- Sajjad
- Typography
- 01 Oct, 2026
Your design system calls for regular text at 400, emphasis at 600, headings at 700, a light 300 for large numbers on the dashboard, and italics for each of those. With traditional fonts that is eight separate files, eight @font-face rules, and eight chances for a swap to happen at a different moment. Then the designer asks for a 650 weight because 600 looks a little thin on dark backgrounds, and there is no such file to load. With a variable font, all of those weights, plus every value in between, come from one file, and 650 is just a number you type.
This article explains what variable fonts are, how they work under the hood, the standard and custom axes you will encounter, the real benefits and the trade-offs, and how to decide whether a variable font is right for your project. The CSS details have their own guide, linked throughout.
What Is a Variable Font?
A variable font is a single font file that contains a continuous range of styles instead of one fixed style. Where a traditional, or static, font file holds exactly one design (for example, Inter Bold), a variable font holds a design space you can move through along one or more axes, such as weight or width.
| Feature | Static fonts | Variable fonts |
|---|---|---|
| Styles per file | One | A continuous range |
| Available weights | Only the ones you load | Any value in the font's range |
| Files for 4 weights | 4 | Usually 1 |
| Width, optical size, etc. | Separate families, if offered | Built-in axes, if the font has them |
| Specification | OpenType, TrueType | OpenType 1.8 and later |
Variable fonts were introduced in OpenType 1.8 in September 2016, announced jointly by Apple, Google, Microsoft, and Adobe. Browser support followed quickly, and today every current version of Chrome, Edge, Firefox, and Safari renders them. Global support is above 97%, so for most sites it is a safe default.
How Variable Fonts Work
Type designers have always drawn families as a set of masters, for example a thin master and a black master, and generated the intermediate weights by interpolating between them. Before variable fonts, that interpolation happened in the designer's software, and only the final instances were exported as separate files.
A variable font ships the interpolation itself. Inside the file:
- Each glyph is stored once, as a default outline.
- For each axis, the file stores deltas: how far each point on the outline moves as you travel along that axis.
- The
fvartable lists the axes, their minimum, default, and maximum values, plus any named instances such as "SemiBold" at weight 600. - Other tables (
gvarfor TrueType outlines,CFF2for PostScript outlines, plusHVAR,MVAR, andSTAT) describe how spacing, metrics, and style names change.
When you ask for weight 650, the rendering engine starts with the default outline and applies the appropriate fraction of each delta. That calculation is cheap, which is why variable fonts render as quickly as static ones in practice.
You can inspect the axes of any variable font with fontTools:
pip install fonttools brotli
from fontTools.ttLib import TTFont
font = TTFont("RobotoFlex-Variable.woff2")
for axis in font["fvar"].axes:
print(axis.axisTag, axis.minValue, axis.defaultValue, axis.maxValue)
Or open the file in a browser-based tool such as Wakamai Fondue, which lists every axis and named instance without installing anything.
Registered Axes
The OpenType specification defines five registered axes. Their tags are lowercase, and each maps to an existing CSS property, so you can control them without low-level syntax.
| Axis tag | Name | Typical range | CSS property |
|---|---|---|---|
wght | Weight | 100–900 | font-weight |
wdth | Width | 75%–125% | font-stretch |
slnt | Slant | -15° to 0° | font-style: oblique |
ital | Italic | 0 or 1 | font-style: italic |
opsz | Optical size | e.g. 8–144 | font-optical-sizing |
- Weight is the axis almost every variable font has. Some go beyond the usual 100–900, for example 1–1000.
- Width lets one family cover condensed through expanded styles, which is useful for tight navigation or responsive headlines.
- Slant gives a mechanically sloped style, while italic switches to genuinely different italic letterforms.
- Optical size adjusts the design for the size it is displayed at: sturdier strokes, looser spacing, and larger x-height at small sizes, finer detail and tighter spacing at large sizes. Browsers set it automatically from the font size. What optical sizing is explains why this matters so much for screen text.
Custom Axes
Type designers can also define their own axes. Custom axis tags are written in uppercase, and you control them with font-variation-settings. Some examples from widely used fonts:
| Font | Axis | What it does |
|---|---|---|
| Roboto Flex | GRAD | Grade: changes stroke weight without changing character width |
| Roboto Flex | XTRA | Adjusts the width of counters (the space inside letters) |
| Recursive | MONO | Moves from proportional to monospaced |
| Recursive | CASL | Moves from a linear to a casual, brush-like style |
| Fraunces | SOFT | Softens the corners and terminals |
| Fraunces | WONK | Toggles quirky, leaning alternate letterforms |
Grade deserves special mention. Changing wght changes the width of letters, so text reflows. Changing GRAD thickens or thins strokes while keeping every glyph the same width. That makes it ideal for hover states that should not shift layout, for compensating for the way light text on dark backgrounds looks heavier, and for adapting to different screen rendering.
Why You Should Use Variable Fonts
1. Fewer files and fewer requests
If you use three or more weights of a family, one variable file usually replaces them all. Fewer files means fewer requests, fewer @font-face rules, and only one swap instead of several staggered ones as each weight arrives. The exact byte savings depend on the font, and the numbers are covered in variable fonts vs. static fonts: a performance comparison.
2. Precise typographic control
You are no longer limited to the weights a foundry decided to export. Need 450 for body text that looks slightly too light at 400 on Windows? Or 750 for headings that feel a touch heavy at 800? Type the value. This is especially useful for tuning a typographic hierarchy where adjacent levels need subtle but clear differences.
3. Responsive typography
Axes respond to CSS, so typography can adapt to context:
- Use a narrower width on small screens so headlines fit without shrinking.
- Use a slightly heavier weight at small sizes and a lighter one at display sizes.
- Let optical sizing adjust detail automatically as fluid type scales.
h1 {
font-weight: 750;
font-stretch: 85%;
}
@media (min-width: 48rem) {
h1 {
font-stretch: 100%;
}
}
4. Better dark mode and accessibility tuning
Light text on dark backgrounds tends to look bolder. With a variable font you can reduce weight or grade slightly in dark mode instead of living with it. You can also offer user preferences, such as a heavier reading weight, without loading extra files.
5. Motion and interaction
Because axes are numbers, they can be transitioned and animated. Hover states that thicken text smoothly, loading indicators, and expressive headlines all become possible without swapping files. How to animate variable font axes with CSS covers this in depth, including how to do it without hurting performance or users who prefer reduced motion.
6. Simpler design tokens
A type system based on numeric weights maps cleanly to design tokens. Designers in Figma, which supports variable font axes, and developers in CSS can share exactly the same values.
The Trade-offs
Variable fonts are not automatically better in every situation.
- One weight is cheaper as a static file. If you only use regular and bold, two small static files can be lighter than a variable file with a wide weight range and extra axes.
- Extra axes add bytes. A font with weight, width, optical size, and grade is larger than one with weight alone. Load only the axes you use, which the Google Fonts API and tools like
fonttools varLib.instancerboth allow. - Not every typeface is available as a variable font. Many older and commercial families are still static only.
- Italics are often a separate file. Many families ship upright and italic as two variable files, because italic letterforms are different designs rather than slanted uprights.
- Rendering differences. Older operating systems sometimes render variable fonts with slightly different hinting than static files. On modern high-density screens this is rarely noticeable.
- Licensing. Some commercial foundries price variable fonts differently from static families. Check the license terms before you commit.
How to Find Variable Fonts
- Google Fonts: filter by "Variable" in the font list. Many popular families, including Inter, Roboto Flex, Recursive, Fraunces, Montserrat, Open Sans, Source Sans 3, and Noto Sans, are variable.
- Commercial foundries: most major foundries now offer variable versions of new releases.
- Adobe Fonts: supports variable fonts for many families in its web projects.
- Test drives: sites such as v-fonts.com and Axis-Praxis let you play with axes before choosing.
When you load from the Google Fonts API, ask for a range instead of individual weights:
<link
rel="stylesheet"
href="https://fonts.googleapis.com/css2?family=Inter:wght@100..900&display=swap"
/>
The 100..900 syntax tells Google to serve the variable file covering the full range. For production, self-hosting is usually better for privacy and speed.
A First Taste of the CSS
You will rarely need more than this to get started. Declare the font with a weight range, then use font-weight as normal:
@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: 420;
}
strong {
font-weight: 650;
}
The range in @font-face tells the browser that this single file covers every weight from 100 to 900, so it never synthesizes bold. Custom axes, font-variation-settings, inheritance pitfalls, and fallbacks are covered step by step in how to use variable fonts in CSS.
When Should You Use a Variable Font?
Use a variable font when:
- You use three or more weights or styles of the same family.
- You want fine-grained weight control or responsive width.
- Your type benefits from optical sizing, for example a serif that has to work at 14px and 72px.
- You plan to animate or interact with typography.
- You want one swap instead of several during page load.
Stick with static fonts when:
- You need only one or two weights and want the smallest possible payload.
- The typeface you need is only available as static files.
- You are targeting very old browsers or environments, such as some email clients, where variable fonts are not supported.
Variable Fonts FAQ
Yes, in every current version of Chrome, Edge, Firefox, and Safari, which covers well over 97% of global users. Browsers that do not support them fall back to the next font in your font-family stack, so text still renders.
No. A variable file is usually larger than a single static weight but smaller than three or four static weights combined. The more weights you would otherwise load, the more a variable font saves.
The slant axis mechanically tilts the upright letterforms by a number of degrees. The italic axis switches to a separately designed italic, where letters such as a and f often change shape. Many families offer only one of them.
Yes. Figma, Sketch, Adobe Illustrator, InDesign, and Photoshop support variable font axes. Designers can choose exact weights like 450 and hand off the same numeric values to developers.
The OpenType specification reserves lowercase tags for registered axes defined by the standard, such as wght and wdth. Type designers use uppercase tags for their own axes so they never clash with future registered axes.
Not in any meaningful way. Interpolating outlines is cheap for modern rendering engines. Performance concerns come from file size and from animating axes in ways that force text to reflow every frame, not from rendering variable fonts themselves.
Conclusion
A variable font packs an entire range of styles into one file by storing outlines once and describing how they change along axes such as weight, width, slant, and optical size. That gives you fewer files and requests, any weight you want instead of a handful of presets, responsive and adaptive typography, and the ability to animate type smoothly.
They are not a universal win. If you use only one or two weights, static files can be lighter, and extra axes cost bytes. But for most modern sites that use a family across body text, emphasis, and headings, a variable font is simpler to manage, more flexible to design with, and usually faster to load. Start by checking whether your chosen typeface has a variable version, load only the axes you need, and let numeric weights replace the old fixed steps.
Here are some useful references for going deeper on variable fonts:
- Google Fonts Knowledge: Introducing variable fonts — a clear introduction to axes, masters, and named instances.
- MDN Web Docs: Variable fonts guide — how variable fonts map to CSS properties and font-variation-settings.
- Microsoft Typography: OpenType design-variation axis tag registry — the official definitions of the registered axes.
- web.dev: Introduction to variable fonts on the web — practical guidance on loading and using variable fonts.
- CSS-Tricks: One File, Many Options: Using Variable Fonts on the Web — an early, still-useful walkthrough of axes and CSS control.


