
For decades, digital typography was static. We treated web fonts like digital versions of lead typesetting: static blocks of weight and style loaded over the network. If you wanted a bold, light, and italic variant of a typeface, you downloaded three separate files, ballooning your page weight.
The advent of Variable Fonts (OpenType Font Variations) changed everything. Instead of discrete files, a single variable font file contains an entire design space of styles. By exposing fluid design axes like weight (wght), width (wdth), and slant (slnt), variable fonts allow developers to treat typography as an elastic, responsive medium.
When we map these axes to real-world inputs—such as scroll position, cursor proximity, audio levels, or ambient light—we enter the realm of Typographic Physics. Here is how you can use variable fonts to build deeply organic, reactive user interfaces.
In traditional graphic design, text is passive. In reactive web design, we can treat text like a physical spring, a liquid, or a light-sensitive surface.
To achieve this, we map dynamic physical inputs to CSS Custom Properties (variables), which then drive the font's internal design axes via the font-variation-settings property.
.reactive-text {
font-family: "YourVariableFont", sans-serif;
/* Bind CSS Custom Properties to the font's variation axes */
font-variation-settings:
"wght" var(--text-weight, 400),
"wdth" var(--text-width, 100);
transition: font-variation-settings 0.1s ease-out;
}
By altering --text-weight and --text-width dynamically with JavaScript, the text reacts smoothly to user behavior.
Imagine an interface where text subtly grows bolder or wider as your mouse approaches it, creating a tactile "magnetic" pull.
To build this, we calculate the mathematical distance between the mouse pointer and the center of our text element. We then map this distance to the font's weight range (e.g., 100 to 900).
const textElement = document.querySelector('.reactive-text');
window.addEventListener('pointermove', (event) => {
const rect = textElement.getBoundingClientRect();
const textX = rect.left + rect.width / 2;
const textY = rect.top + rect.height / 2;
// Calculate Euclidean distance between pointer and element center
const distance = Math.hypot(event.clientX - textX, event.clientY - textY);
// Set boundaries for our effect (e.g., 400px radius)
const maxDistance = 400;
const proximity = Math.max(0, Math.min(1, (maxDistance - distance) / maxDistance));
// Map proximity to a font weight range of 100 (thin) to 900 (black)
const minWeight = 100;
const maxWeight = 900;
const weight = minWeight + (proximity * (maxWeight - minWeight));
// Update the CSS Custom Property
textElement.style.setProperty('--text-weight', weight);
});
With this script active, as the pointer glides closer, the characters expand and thicken organically, establishing an intuitive, interactive hierarchy.
We can also tie typography to the physical physics of scrolling. As a user scrolls faster, the text can stretch or lean forward, mimicking inertia, before snapping back to its natural state when the scroll stops.
Using a simple delta calculation of the window’s scroll position, we can map kinetic energy to a custom width (wdth) or slant (slnt) axis:
let lastScrollY = window.scrollY;
let velocity = 0;
function updatePhysics() {
const currentScrollY = window.scrollY;
const delta = Math.abs(currentScrollY - lastScrollY);
// Decay the velocity over time to simulate friction
velocity = velocity * 0.9 + delta * 0.1;
// Map velocity to font width (e.g., 75% to 125%)
const minWidth = 75;
const maxWidth = 125;
const calculatedWidth = Math.min(maxWidth, minWidth + (velocity * 2));
document.body.style.setProperty('--text-width', calculatedWidth);
lastScrollY = currentScrollY;
requestAnimationFrame(updatePhysics);
}
requestAnimationFrame(updatePhysics);
While kinetic typography is incredibly engaging, we must balance creativity with usability and performance:
prefers-reduced-motion media query to accommodate users with vestibular motion disorders.width or margin) triggers browser repaints. Because variable font changes trigger a redraw of the text vector, keep your interactive text elements isolated and use CSS transitions wisely to maintain a steady 60fps.@media (prefers-reduced-motion: reduce) {
.reactive-text {
transition: none;
font-variation-settings: "wght" 400, "wdth" 100;
}
}
Typographic physics shifts typography from a static communication tool into an interactive sensory layer. By treating fonts as malleable physical materials, you create interfaces that feel alive, intuitive, and unforgettable. Next time you design a digital space, don't just choose a font—think about how it should move, bend, and react.
Photo by Google DeepMind on Pexels