motion-font

Animates one or more variable font axes — weight, optical size, width, or any custom axis — using Motion One spring physics. Three trigger modes: auto (viewport entry), hover (mouse/focus), and scroll (axis tracks scroll position). Requires a variable font with the targeted axes.

Live showcase Weight spectrum · Word cloud · Spring bounce

Hover — weight

The most common use: bold on hover with a spring-back on leave.

Hover to bold

Auto — viewport reveal

Animates the axis once when the element scrolls into view. Ideal for hero headings that gain weight on entrance.

Weight reveal

Scroll — tied to position

The axis value maps directly to scroll progress — from when the element enters the viewport, to when it exits. No spring; direct 1:1 mapping. Works best in real page context — see the showcase.

Multiple axes

Use the axes prop to animate several axes at once. Format: space-separated tag:from:to triplets. Overrides axis, from, and to.

Hover — weight & optical size

Bounce

Control spring overshoot with bounce (0–1). Higher values overshoot and snap back.

Aa bounce=0
Aa bounce=0.3
Aa bounce=0.6

Delay

Delay the animation start in seconds — useful for staggering multiple reveals.

First line Second line Third line

Properties

Attribute Property Type Default Description
axis axis string 'wght' Font axis tag — 'wght', 'wdth', 'opsz', or any custom axis. Ignored when axes is set.
axes axes string '' Multi-axis: space-separated tag:from:to triplets, e.g. "wght:300:800 opsz:8:32". Overrides axis, from, to.
from from number 300 Starting axis value. Ignored when axes is set.
to to number 700 Target axis value. Ignored when axes is set.
duration duration number 0.6 Spring duration hint in seconds.
bounce bounce number 0 Spring bounciness 0–1. 0 = no overshoot, 1 = very bouncy.
delay delay number 0 Delay before animation starts in seconds.
trigger trigger string 'auto' 'auto' — viewport entry  |  'hover' — mouseenter / focusin  |  'scroll' — axis tracks scroll position
once once boolean true For trigger='auto': animate only on the first intersection.

Methods

Method Type Default Description
replay() void Reset axis to from and re-run the entrance animation. Only has effect for trigger="auto".

Variable font required: the targeted axis must exist in the loaded font. Inter supports wght (100–900) and opsz (14–32). For wdth use a font like Roboto Flex.

Accessibility

Respects prefers-reduced-motion: when enabled, axis animations are skipped and the font renders at its target value immediately.