opszstepper
Optical cuts,
on demand.
Type designers create separate optical-size cuts for the same reason optometrists prescribe different lenses for reading and driving — the geometry that works at 12px becomes wrong at 72px. Opsz Stepper detects the current font-size and hot-swaps to the correct cut, automatically.
Live demo — drag the sliders
How it works
Optical sizes are different drawings
Micro, Text, and Display variants of the same typeface aren't simply scaled versions of each other. They have different stroke widths, apertures, x-heights, and spacing — each redrawn from scratch to be optically correct at its intended size range.
ResizeObserver watches the element
When the element's computed font-size changes — because of responsive CSS, viewport units, or user zoom — the ResizeObserver fires. Opsz Stepper re-reads the font-size and re-evaluates which cut to apply, keeping the typeface optically correct at every size.
Hysteresis prevents oscillation
If font-size sits exactly at a cut boundary — say, precisely 16px — the element would flip between cuts on every resize event. The hysteresis dead zone prevents this: font-size must pass the boundary by N pixels before the cut switches, so the boundary feels stable rather than jittery.
Works with any font family
Cuts are just CSS font-family strings. Google Fonts, locally hosted @font-face declarations, cloud fonts, Adobe Fonts — anything you can name in CSS works as a cut. The tool makes no assumptions about the fonts themselves.
Usage
TypeScript + React · Vanilla JS
Drop-in component
import { OpszStepperText } from '@liiift-studio/opszstepper'
<OpszStepperText cuts={[
{ family: 'Halyard Micro, sans-serif', maxSize: 13 },
{ family: 'Halyard Text, sans-serif', minSize: 13, maxSize: 28 },
{ family: 'Halyard Display, sans-serif', minSize: 28 },
]}>
Your text here
</OpszStepperText>Hook — attach to any element
import { useOpszStepper } from '@liiift-studio/opszstepper'
const ref = useOpszStepper({ cuts })
<p ref={ref}>Your text</p>Vanilla JS
import { startOpszStepper } from '@liiift-studio/opszstepper'
const el = document.querySelector('h1')
const stop = startOpszStepper(el, { cuts })
// Call stop() to disconnect and restore original fontFamilyOptions
| Option | Default | Description |
|---|---|---|
| cuts | required | Array of OpszStepperCut objects, each with a family string and optional minSize/maxSize in px. |
| hysteresis | 1 | Dead zone in px at each cut boundary. Prevents oscillation when font-size sits exactly at a threshold. |
| onCutChange | — | Callback fired each time the active cut changes. Receives the new OpszStepperCut object. |
| as | 'p' | HTML element to render. Accepts any valid React element type. (OpszStepperText only) |