In 2016, an important development in web typography was jointly announced by representatives from Adobe, Microsoft, Apple, and Google. Version 1.8 of the OpenType font format introduced variable fonts. With so many big names involved, it’s unsurprising that all browsers are on-board and racing ahead with implementation.
Font weights can be far more than just bold
and normal
—most professionally designed typefaces are available in variants ranging from a thin hairline
ultralight to a black
extra-heavy bold. To make use of all those weights, we would need a separate file for each. While a design is unlikely to need every font-weight, a wider variety than bold and normal adds visual hierarchy and interest to a page.

There’s more than various weights to consider. CSS3 introduced the font-stretch
property, with values from ultra-condensed
to ultra-expanded
. Until now, these values only worked if you provided a separate file for each width. If you wanted every combination of weight and width in both normal and italic, you would need dozens of files.

With variable fonts, we can get all this variety with a single file.
The OpenType spec lists five standard axes of variation—all labeled by a four-character string. These are aspects of the typeface that we have control over.
wght
– Weight is controlled by the CSSfont-weight
property. The value can be anything from 1 to 999. This will allow for a more granular level of control.wdth
– Width is controlled by the CSSfont-stretch
property. It can take a keyword or a percentage value. While it’s long been possible to use a transform toscaleX
orscaleY
, that distorts the font in ugly ways unintended by the typographer. The width axis is defined by the font designer to expand or condense elegantly.opsz
– Optical sizing can be turned on or off using the newfont-optical-sizing
property. (I’ll explain what optical sizing is later on.)ital
– Italicization is achieved by setting the CSSfont-style
property toitalic
slnt
– Slant is controlled by setting the CSSfont-style
property set tooblique
. It will default to a 20 degree slant but it can also accept a specified degree between-90deg
and90deg
.
Unfortunately, not every variable font will necessarily make use of all five axes. It’s entirely dependent on the creator of the particular typeface. After testing every variable font I could get my hands on, by far the most commonly implemented is weight, followed closely by width. Much of the time you will need two files: one for italic and one for regular, as the ital
axis isn’t always implemented. As Frank Grießhammer of Adobe told me:
Italic and Roman styles have (often radically) different construction principles, therefore point structures may not always be compatible.
The browser can make any non-italic font emulate italics, but this is typographically ill-advised.
Typographers can define named instances within their variable font. A named instance is a preset—a particular variation the font is capable of accessing with a name (e.g. “Extra Light”) rather than with numbers alone. In the current CSS spec, however, there is no way to access these named instances. It’s important to note that when you use a value like extra-condensed
or semi-expanded
for font-stretch
, the value maps to a percentage predefined in the CSS spec—not to any named instance chosen by the font creator. For font-weight
, the bold
value maps to 700
and normal
to 400
. As the spec puts it, “a font might internally provide its own mappings, but those mappings within the font are disregarded.”
The CSS Fonts Module Level 4 spec introduces the new font-variation-settings
property to control variable font options. The following two CSS declarations are equivalent:
h1 {
font-weight: 850;
font-style: italic;
font-stretch: normal;
}
h1 {
font-variation-settings: "wght" 850, "wdth" 100, "ital" 1;
}
The spec strongly prefers using font-optical-sizing
, font-style
, font-weight
and font-stretch
over font-variation-settings
for controlling any of the five standard axes. As Myles Maxfield kindly explained to me:
font-variation-settings
is not identical to the other variation-aware properties, because with these other properties, the browser has insight into the meaning of the variations, and can therefore do things like applying them to other font file formats, or creating synthesized versions if the font file doesn’t support the axis.
Microsoft will register more standard axes tags over time. As new axes are added, we can also expect new CSS properties to control them. Font creators are also free to invent their own axes. This is why font-variation-settings
was added to CSS—it is the only way to control custom axes. Lab DJR and Decovar are two typeface made with the express intention of demonstrating just how malleable a single variable font can be. Lab DJR, for example, offers four custom axes:
h1 {
font-variation-settings: 'SIZE' 100, 'QUAD' 80, 'BEVL' 950, 'OVAL' 210;
}

These foundry-defined custom axes must use uppercase letters while the standardized axes always use lower case. With unique and unstandardized options, CSS authors must count on font developers to properly document their work.

Performance
You might download a variable font in TTF format rather than as a pre-compressed file. You’ll definitely want to convert it into .woff2
. Google offer a command line tool predictably named woff2 to make it easy. If you cd
into the folder containing your font while in the command line, you can type:
woff2_compress examplefont.ttf
We’ve established that we’ll only need one HTTP request per typeface (or possibly two to separate Roman and Italic styles). Because they’re doing so much work, you might expect the file size of a variable font to be far larger than a typical font file. Let’s have a (not entirely scientific) look.
Here are some of the variable fonts I have hanging around my laptop, along with their file sizes:

71 KB
even though it has 15 axesLet’s compare that to single instances of a non-variable version of Source Sans:

Animation
Variable fonts also mean that, for the first time, font-weight
(and any other axis) can be animated. While adding type animation may sound like a superfluous embellishment a website can happily survive without, something like adding weight on focus, for example, seems like a natural and intuitive way to denote state to the user. In the past, switching from a normal to a bold weight was utterly jarring. With variable fonts it can be smooth and graceful.
One Size Fits All?
While Lab DJR and Decovar are excitingly creative, variable fonts aren’t all about avant-garde experimentalism. Optical sizing should bring a better reading experience to the web. Currently, type on the web is size agnostic; you can change the font-size
and it will still look the same. Optical sizing means making size-specific optimizations for a typeface where the variation of a letter’s form at different sizes can improve readability. We don’t want larger text to look inelegant or clunky, while smaller text benefits from the removal of fine details. More open counters, the thickening of subtle serifs, and an increase in x-height, width, weight and letter-spacing all improve legibility at smaller sizes. The initial value is auto
so if you are using a font that makes use of an optical sizing index, you get the benefit for free out of the box.
What Fonts Are Available?
This technology is quickly making its way into browsers. Making use of it requires you to find a variable font you actually want to use. Google Fonts Early Access has three available, with many more likely to follow. Adobe is remaking some of the most well-known families (i.e. Minion, Myriad, Acumin) to be variable. The open source fonts Source Sans and Source Serif have also been released. Monotype, one of the world’s largest typography companies, has so far introduced beta versions of Avenir Next and Kairos Sans. Some independent type foundries have also started to release variable typefaces. With variable font support now available in all major font-creation software, we can expect the availability to greatly expand over 2018.
Using Your Font
Once you’ve found your font, you need to use @font-face
to include it on your site.
We don’t want any browsers to download a font they can’t use. For that reason, we should specify the format inside the @font-face
rule. Depending on the file type of your variable font, you can specify woff-variations
, woff2-variations
, opentype-variations
or truetype-variations
. As already mentioned, you should always use woff2
.
@font-face {
font-family: 'source sans';
src: url(SourceSansVariable.woff2) format("woff2-variations"),
url(SourceSans.woff2) format("woff2"); /* for older browsers */
font-weight: normal; font-style: normal;
}
@font-face {
font-family: 'source sans';
src: url(SourceSansVariable-italic.woff2) format("woff2-variations"),
url(SourceSans-italic.woff2) format("woff2");
font-weight: normal; font-style: italic;
}
A third @font-face
is only necessary to provide a backup bold font for browsers that do not support variable fonts. Notice that we are using the same variable font file as for the first @font-face
rule, as that file can be both bold and normal:
@font-face {
font-family: 'source sans';
src: url(SourceSansVariable.woff2) format("woff2-variations"),
url(SourceSans-bold.woff2) format("woff2");
font-weight: 700; font-style: normal;
}
If the browser supports variable fonts, SourceSansVariable.woff2
and SourceSansVariable-italic.woff2
will be downloaded and used. If not, SourceSans.woff2
, SourceSans-bold.woff2
and SourceSans-italic.woff2
will be downloaded instead.
From here, we can apply the font on an element as we normally would:
html {
font-family: 'source sans', Verdana, sans-serif;
}
San Francisco
While variable fonts bring performance benefits, “web-safe” system fonts still remain the most performant option because the font is already installed and there is nothing to download. If you want to use a variable font without the need of downloading anything, Apple’s San Francisco, perhaps the prettiest of all system fonts, is also a variable font. Using system fonts no longer requires a massive font-stack:
html {
font-family: system-ui, -apple-system;
}
The system-ui
value is the new standard to access system fonts, while -apple-system
is non-standardized syntax that works on Firefox. Traditionally, system fonts have not come in a wide range of weights or widths. Hopefully more will be made available as variable fonts, bringing all the benefits of variable fonts without a single HTTP request.
Browser Support
Variable fonts have shipped in Chrome and Safari. They are already in the insider preview version of Edge and behind a flag in Firefox. At the current time, not all parts of the spec are fully implemented by Chrome. Using variable fonts in conjunction with font-style
, font-stretch
, font-weight
and font-optical-sizing
does not work in Chrome, so using font-variation-settings
to control the five standard axes is necessary for the time being. Specifying the format as woff2-variations
inside of @font-face
also lacks support in Chrome (you can specify only woff2
and the font will still work, but then you are unable to have a non-variable woff2 fallback).
David Jonathan Ross, one of the type designers that is already dealing with var fonts in html, has suggested the use of @supports CSS declaration in order to have fallback in case the browser does not support Variable fonts yet. Maybe showing this method on this tutorial can help too. (https://developer.mozilla.org/pt-BR/docs/Web/CSS/@supports)