fitwidth
Fill any width,
exactly.
CSS can't make a display headline fill its container — letter-spacing is proportional, and the wdth axis affects every character equally. Fit Width binary-searches both to converge on an exact width to within half a pixel.
Live demo — drag the slider
How it works
CSS can't fit a headline
letter-spacing adds a fixed amount after every character — it's proportional, not absolute. The wdth axis scales character shapes but doesn't guarantee a target width. Neither can converge on an exact measurement alone.
Binary search converges in 20 iterations
Fit Width uses a classic binary search: measure the element, compare to target, move the midpoint. Within 15–20 iterations it converges to within the tolerance (default 0.5 px). The cost is negligible — no reflow until the final write.
Axis first, then tracking
In prefer='auto' mode, Fit Width tries the wdth axis first. If the axis range isn't enough to reach the target, letter-spacing closes the remaining gap. Either strategy can be used exclusively via 'axis' or 'tracking'.
Idempotent — call it again on resize
Original inline styles are saved on the first call and restored before each re-fit. It's safe to call applyFitWidth repeatedly. useFitWidth and FitWidthText wire up a ResizeObserver and document.fonts.ready automatically.
Usage
TypeScript + React · Vanilla JS
Drop-in component
import { FitWidthText } from '@liiift-studio/fitwidth'
<FitWidthText prefer="auto">
Display Headline
</FitWidthText>Hook — attach to any element
import { useFitWidth } from '@liiift-studio/fitwidth'
const ref = useFitWidth({ prefer: 'auto' })
<h1 ref={ref}>Display Headline</h1>Vanilla JS
import { applyFitWidth, removeFitWidth } from '@liiift-studio/fitwidth'
const el = document.querySelector('h1')
applyFitWidth(el, { prefer: 'auto' })
// Restore original styles
removeFitWidth(el)Options
| Option | Default | Description |
|---|---|---|
| target | 'container' | Width to fill: 'container' (parent clientWidth), a pixel number, or an HTMLElement. |
| prefer | 'auto' | 'auto' — wdth axis first, then letter-spacing. 'axis' — axis only. 'tracking' — letter-spacing only. |
| axis | 'wdth' | Variable font axis tag to binary-search. |
| axisMin | 75 | Minimum axis value for the binary search. |
| axisMax | 125 | Maximum axis value for the binary search. |
| maxTracking | 0.3 | Maximum absolute letter-spacing in em (clamped to ±this value). |
| tolerance | 0.5 | Convergence tolerance in pixels — search stops when within this gap. |
| as | 'h1' | HTML element to render. Accepts any valid React element type. (FitWidthText only) |