Variable Font Hover By Letter
A text component that animates the font variation settings of letters. Works only with variable fonts.
OPEN ROLES ✽
- DESIGN ENGINEER (US)PRODUCT DESIGNER (US/UK)ENGINEERING MANAGER (US)SALES ENGINEER (US)
Source code
Install the following dependencies:
npm install lodash
lodash is used for debouncing here — so the animation doesn't break on rapid hover changes.
Copy and paste the following code into your project:
Understanding Variable Fonts
This component is designed to work exclusively with variable fonts. Variable fonts are a modern font technology that allows a single font file to contain multiple variations of a typeface — these variations can be adjusted along different axes, such as weight, width, or slant, etc.
Each axis in a variable font has a minimum and maximum value, and you can interpolate between these values to create custom styles. Common axes include:
- Weight (
wght
): Controls the thickness of the letterforms (usually ranges from 100 to 900) - Width (
wdth
): Controls the width of the letterforms - Slant (
slnt
): Changes the angle of the letterforms - Italic (
ital
): Also controls the slant of the letterforms - Optical Size (
opsz
): Controls the size of the letterforms
These 5 axes are actually standardized, so when a font have them, they will have the names above. But, a font can have limitless custom axes too, with completely arbitrary names.
In this component, the fromFontVariationSettings
and toFontVariationSettings
props define the starting and ending states of the font variation. For example, using the Overused Grotesk font (which we use in this demo), we can modify the 'slnt' (slant) and 'wght' (weight) axes:
- The
slnt
axis ranges from 0 (up) to -10 (upright) - The
wght
axis ranges from 100 (thin) to 900 (black)
An example prop therefore would be:
fromFontVariationSettings="'wght' 100, 'slnt' 0"
Always check the font's documentation to see what are the available axes and their ranges.
Important to mention that older browser versions and various environments don't support variable fonts, so make sure to check compatibility.
Resources
I highly recommend to go down the rabbit hole, it's super fun :)
Props
Prop | Type | Default | Description |
---|---|---|---|
label* | string | - | The text to be displayed and animated |
fromFontVariationSettings* | string | - | Initial font variation settings |
toFontVariationSettings* | string | - | Target font variation settings on hover |
className | string | - | Additional CSS classes for styling |
transition | DynamicAnimationOptions | { type: "spring", duration: 0.7 } | Transition settings for the animation. Refer to framer-motion docs for more details |
staggerDuration | number | 0.03 | Delay between each letter's animation start |
staggerFrom | "first" | "last" | "center" | number | "first" | Starting point of the stagger effect. Number is the index of the letter where the stagger animation starts |
onClick | () => void | - | Callback function for click events |