revision:
Variable fonts are an evolution of the OpenType font specification that enables many different variations of a typeface to be incorporated into a single file, rather than having a separate font file for every width, weight, or style. They let you access all the variations contained in a given font file via CSS and a single @font-face reference.
Standard (or static) fonts: in the past, a "typeface" would be produced as a number of individual fonts, and each font would represent one specific width/weight/style combination.
So you would have separate files for 'Roboto Regular', 'Roboto Bold', and 'Roboto Bold Italic' — meaning that you could end up with 20 or 30 different font files to represent a complete typeface (it could be several times that for a large typeface that has different widths as well).
In such a scenario, in order to use a typeface for typical use on a site for body copy you would need at least four files: regular, italic, bold, and bold italic. If you wanted to add more weights, like a lighter one for captions or a heavier one for extra emphasis, that would mean several more files.
This results in more HTTP requests, and more data being downloaded (usually around 20k or more per file).
With variable fonts all of those permutations can be contained in a single file. That file would be larger than a single font, but in most cases smaller or about the same size as the 4 you might load for body copy.
The advantage in choosing the variable font is that you have access to the entire range of weights, widths, and styles available, rather than being constrained to only the few that you previously would have loaded separately.
This allows for common typographic techniques such as setting different size headings in different weights for better readability at each size, or using a slightly narrower width for data-dense displays.
Axis of variation: the heart of the new variable fonts format is the concept of an "axis of variation" describing the allowable range of that particular aspect of the typeface design.
So the 'weight axis' describes how light or how bold the letterforms can be.
The 'width axis' describes how narrow or how wide they can be.
The 'italic axis' describes if italic letterforms are present and can be turned on or off accordingly.
etc.
Note that an axis can be a range or a binary choice. Weight might range from 1–999, whereas italic might be 0 or 1 (off or on).
There are two kinds of axes: registered and custom:
Registered axes are those that are most frequently encountered, and common enough that the authors of the specification felt it was worth standardizing.
The five currently registered axes are weight, width, slant, italic, and optical size. The W3C has undertaken mapping them to existing CSS attributes, and in one case introduced a new one.
Custom axes are in fact limitless: the typeface designers can define and scope any axis they like.
They are just required to give it a four-letter tag to identify it within the font file format itself.
You can use these four-letter tags in CSS to specify a point along that axis of variation.
Weight (represented by the "wght" tag) defines the design axis of how thin or thick (light or heavy, in typical typographic terms) the strokes of the letterforms can be.
For a long time in CSS there has existed the ability to specify this via the "font-weight" property, which takes numeric values ranging from 100 to 900 in increments of 100, and keywords like "normal" or "bold", which are aliases for their corresponding numeric values (400 and 700 in this case).
These are still applied when dealing with non-variable or variable fonts, but with variable ones, any number from 1 to 1000 is now valid.
It should be noted that at this point there is no way in the @font-face declaration to 'map' a specific point on the variation axis of a variable font to the keyword "bold" (or any other keyword). This can generally be resolved fairly easily, but does require an extra step in writing your CSS:
Width (represented by the "wdth" tag) defines the design axis of how narrow or wide (condensed or extended, in typographic terms) the letterforms can be.
This is typically set in CSS using the "font-stretch" property, with values expressed as a percentage above or below ‘normal’ (100%).
Any number greater than 0 is technically valid—though it is far more likely that the range would fall closer to the 100% mark, such as 75%-125%.
If a number value supplied is outside the range encoded in the font, the browser should render the font at the closest value allowed.
The Italic (ital) axis works differently in that it is either on or off; there is no in-between. b
Italic designs often include dramatically different letterforms from their upright counterparts, so in the transition from upright to italic, a number of glyph (or character) substitutions usually occur.
Italic and oblique are often used somewhat interchangeably, but in truth are actually quite different. Oblique is defined in this context with the term slant, and a typeface would typically have one or the other, but not both.
In CSS, both italic and oblique are applied to text using the "font-style" property. Also note the introduction of "font-synthesis: none;" — which will prevent browsers from accidentally applying the variation axis and a synthesized italic. This can be used to prevent faux-bolding as well.
Slant (represented by the "slnt" tag) - or as it's often referred to, 'oblique' - is different to true italics in that it changes the angle of the letterforms but doesn’t perform any kind of character substitution.
It is also variable, in that it is expressed as a numeric range. This allows the font to be varied anywhere along that axis.
The allowed range is generally 0 (upright) to 20 degrees — any number value along that range can be supplied, so the font can be slanted just a tiny bit. However, any value from -90–90 degrees is valid.
Optical size is something new to digital fonts and CSS, but is actually a centuries-old technique in designing and creating metal type.
Optical sizing refers to the practice of varying the overall stroke thickness of letterforms based on physical size.
Optical size values are generally intended to be automatically applied corresponding to font-size, but can also be manipulated using the lower-level font-variation-settings syntax.
When using "font-optical-sizing", the only allowed values are "auto" or "none" — so this attribute only allows for turning optical sizing on or off.
However when using "font-variation-settings: 'opsz' < num>", you can supply a numeric value.
In most cases you would want to match the font-size (the physical size the type is being rendered) with the "opsz" value (which is how optical sizing is intended to be applied when using auto).
The option to provide a specific value is provided so that should it be necessary to override the default — for legibility, aesthetic, or some other reason — a specific value can be applied.
Custom axes can be any axis of design variation that the typeface designer imagines.
There may be some that become fairly common — or even become registered — but only time will tell.
Grade may become one of the more common custom axes as it has a known history in typeface design.
The practice of designing different grades of a typeface was often done in reaction to intended use and printing technique.
The term 'grade' refers to the relative weight or density of the typeface design, but differs from traditional 'weight' in that the physical space the text occupies does not change. So changing the text grade doesn't change the overall layout of the text or elements around it.
This makes grade a useful axis of variation as it can be varied or animated without causing reflow of the text itself.
The syntax for loading variable fonts is very similar to any other web font, with a few notable differences, which are provided via upgrades to the traditional @font-face syntax now available in modern browsers.
The basic syntax is the same, but the font technology can be specified, and allowable ranges for descriptors like "font-weight" and "font-stretch" can be supplied, rather than named according to the font file being loaded.
@font-face is a "CSS at-rule" used to define custom fonts. With @font-face, you provide a path to a font file hosted on the same server as your CSS file. The rule has been around for quite some time, but there is a newer property, "font-display", which brings a new level of loading options.
Example 1: example for a standard upright (Roman) font:
@font-face { font-family: 'MyVariableFontName'; src: 'path/to/font/file/myvariablefont.woff2' format('woff2-variations'); font-weight: 125 950; font-stretch: 75% 125%; font-style: normal; }
Example 2: example for a font that includes both upright and italics:
@font-face { font-family: 'MyVariableFontName'; src: 'path/to/font/file/myvariablefont.woff2' format('woff2-variations'); font-weight: 125 950; font-stretch: 75% 125%; font-style: oblique 0deg 20deg; }
Example 3: example for a font that contains only italics and no upright characters:
@font-face { font-family: 'MyVariableFontName'; src: 'path/to/font/file/myvariablefont.woff2' format('woff2-variations'); font-weight: 125 950; font-stretch: 75% 125%; font-style: italic; }
The font-variation-settings property is an animatable property.
You can use it to animate any of the variable axes of a given variable font by using the four letter axis name and providing a value within its accepted range.
That sounds a bit complex, but essentially it means that what you can animate via this property depends on the font you’re using.
The exact values will vary from font to font, but it will look a little something like this:
font-variation-settings: "MONO" 0, "CASL" 1, "CRSV" 0, "wght" 1000, "slnt" 0;