Understand what variable fonts are and how they differ from static fonts
Use the five standard axes: weight, width, slant, italic, and optical sizing
Control weight with font-weight for any value from 100-900
Access custom axes with font-variation-settings for unique effects
Load variable fonts from Google Fonts or self-host with @font-face
Create smooth animations between weights impossible with static fonts
Build responsive typography that adapts weight to viewport size
Understand performance benefits: one file vs multiple static weights
Explore popular variable fonts and where to find them
Introduction to Variable Fonts
Variable fonts are a powerful evolution in web typography. Instead of loading separate font files for each weight (regular, medium, bold, etc.), a variable font contains multiple variations along adjustable design axes in a single file. This provides infinite flexibility while often reducing total file size.
Introduced in OpenType 1.8 (2016) and supported in all modern browsers since 2017-2018, variable fonts solve the performance problem of loading multiple font weights while giving designers unprecedented control over typography. One variable font file can replace 5-10 static font files.
Traditional vs Variable Fonts
To understand the revolution variable fonts bring, compare them to traditional static fonts:
Traditional Static Fonts:
• Separate file for each weight/style
• Roboto Regular (28KB) + Medium (29KB) + Bold (31KB) = 88KB, 3 files
• Only specific weights available (400, 500, 700)
• Can't use intermediate values (no 650)
• Can't animate between weights
• Multiple HTTP requests slow loading
Variable Fonts:
• Single file with full weight range
• Inter Variable (120KB) = 100-900, 1 file
• Any weight value (437, 550, 680, etc.)
• Smooth animations between weights
• Single HTTP request, faster loading
• Often smaller than loading 3-4 static weights
Standard Axes
Variable fonts adjust along "axes" - design parameters that can vary. Five standard axes have dedicated CSS properties, while custom axes use font-variation-settings.
/* Five standard (registered) axes */
font-weight: 100 to 900; /* wght - thickness */
font-stretch: 50% to 200%; /* wdth - character width */
font-style: oblique -20deg to 20deg; /* slnt - slant angle */
font-style: italic; /* ital - italic on/off (0 or 1) */
font-optical-sizing: auto; /* opsz - optical size */
/* Examples */
h1 {
font-weight: 650; /* Any value 100-900! */
font-stretch: 115%; /* Slightly expanded */
font-style: oblique 12deg; /* 12-degree slant */
}
/* Optical sizing (automatic in many browsers) */
.large-heading {
font-size: 4rem;
font-optical-sizing: auto; /* Optimizes for size */
}
Weight Axis (wght) - Infinite Flexibility
The weight axis is the most common and useful. Unlike static fonts limited to specific weights (100, 200, 300, etc.), variable fonts support ANY value in their range.
/* Static fonts: limited to specific weights */
font-weight: 400; /* Regular */
font-weight: 700; /* Bold */
font-weight: 650; /* NOT AVAILABLE - browser rounds to 700 */
/* Variable fonts: any value in range */
font-weight: 400; /* Regular */
font-weight: 700; /* Bold */
font-weight: 650; /* ✓ Exactly 650! */
font-weight: 437; /* ✓ Works! */
font-weight: 826; /* ✓ Fine-tune as needed */
/* Practical use cases */
h1 {
font-weight: 750; /* Heavier than bold but not too heavy */
}
.subtitle {
font-weight: 450; /* Slightly heavier than regular */
}
.footnote {
font-weight: 350; /* Lighter than regular */
}
Custom Axes with font-variation-settings
Some variable fonts include custom axes beyond the five standard ones. These require font-variation-settings and use four-letter tags (usually uppercase for custom axes).
/* font-variation-settings syntax */
font-variation-settings: 'AXIS' value, 'AXIS' value;
/* Recursive font with CASL (casual) and MONO (monospace) axes */
.linear-mono {
font-family: 'Recursive', monospace;
font-variation-settings: 'CASL' 0, 'MONO' 1;
/* Linear style, monospace spacing */
}
.casual-proportional {
font-family: 'Recursive', monospace;
font-variation-settings: 'CASL' 1, 'MONO' 0;
/* Casual style, proportional spacing */
}
/* Roboto Flex with GRAD (gradient/stroke) */
.text-gradient {
font-family: 'Roboto Flex', sans-serif;
font-variation-settings: 'GRAD' 150;
/* Adjusts stroke thickness */
}
/* Combining standard and custom axes */
.advanced {
font-weight: 600; /* Standard axis */
font-variation-settings: 'GRAD' 100, 'slnt' -8;
/* Custom GRAD + standard slnt */
}
Loading Variable Fonts
Variable fonts can be loaded from CDNs like Google Fonts or self-hosted with @font-face. The syntax is similar to static fonts with one key difference: specify the axis range.
<!-- Google Fonts variable font -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<!-- Load full weight range (100-900) with .. notation -->
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@100..900&display=swap" rel="stylesheet">
<!-- Use in CSS -->
body {
font-family: 'Inter', sans-serif;
font-weight: 525; /* Any value in 100-900 range */
}
/* Self-hosted variable font with @font-face */
@font-face {
font-family: 'InterVariable';
src: url('../fonts/inter-variable.woff2') format('woff2-variations'),
url('../fonts/inter-variable.woff2') format('woff2');
font-weight: 100 900; /* Specify range! */
font-stretch: 75% 125%; /* If font supports width axis */
font-display: swap;
}
body {
font-family: 'InterVariable', sans-serif;
font-weight: 450; /* Use any value in range */
}
/* Multiple axes */
@font-face {
font-family: 'RobotoFlex';
src: url('roboto-flex.woff2') format('woff2-variations');
font-weight: 100 1000;
font-stretch: 25% 151%;
font-display: swap;
}
Animating Variable Fonts
One of the most exciting capabilities of variable fonts is smooth animation between weights, widths, or other axes. This is impossible with static fonts.