bold-lock
Bold on hover.
Zero layout shift.
Every browser will reflow text when you hover to bold — words push down, lines shift. Bold Lock measures the exact width difference using Canvas, then compensates with letter-spacing so the line never moves.
Live demo — hover the paragraph
Hover over this paragraph to feel the weight change. The font grows heavier as your cursor moves over the text — but look carefully: the line endings stay exactly where they are. No word wraps to the next line. No layout shifts. The trick is measuring the width difference between the two weights using Canvas, then compensating with letter-spacing so the total advance width stays constant. Bold text normally pushes words around. This doesn't.
Move your cursor over the paragraph. Line endings stay fixed.
The problem with bold hover
Why text reflows
Bold glyphs are wider. When you change font-weight on hover, every character in the element grows slightly, words push into the next line, and the whole paragraph reflts. It's jarring and there's no CSS fix.
How we fix it
Canvas measureText gives us the exact advance width of each line at both weights. The difference becomes a negative letter-spacing compensation applied on hover, so total line width stays identical. One measurement pass on mount, zero reflow on hover.
Usage
Drop-in component
import { BoldLockText } from '@liiift-studio/bold-lock'
<BoldLockText normalWeight={300} hoverWeight={700} transitionDuration={150}>
Hover over this text...
</BoldLockText>Hook
import { useBoldLock } from '@liiift-studio/bold-lock'
const ref = useBoldLock({ normalWeight: 300, hoverWeight: 700 })
<p ref={ref}>{children}</p>Options
| Option | Default | Description |
|---|---|---|
| normalWeight | computed | Font weight at rest. |
| hoverWeight | 700 | Font weight on hover. |
| transitionDuration | 150 | Transition duration in milliseconds. |
| mode | 'element' | 'element' = whole element hovers together, 'word' = individual word hover. |