01Weight Without Width
Watch the top row. Each word gets bolder in turn, and everything after it shuffles along. Now the bottom row. Same words, just as bold, and nothing moves. That difference is what I’ve been chasing.
02The problem
You’ve seen this a thousand times. You hover a menu item, it goes bold, and the whole menu twitches. Nav bars, tabs, those little filter chips: anywhere bold means you’re here. Bold letters are wider than regular ones, so the word grows, and the rest of the line moves over to make room.
03Asked in 2009
People have been asking about this for a long time. In February 2009 someone posted it on Stack Overflow: inline elements shifting when made bold on hover. The first answer, the same morning, said there was no way to avoid it, except by compromises like fixed widths. That question has had about a quarter of a million views. And by the end of 2009 people were already patching it with JavaScript.
04The workarounds
So we built workarounds. The best one is pure CSS: you hide a bold copy of the label behind the real one, so the box is already wide enough. For a nav bar, honestly, it works well. Microsoft and GitHub both ship it in their tab components, with comments in the code saying why. The cost is empty space around every label at rest. Some people fake the boldness with a text shadow or a stroke, which never quite looks like bold. And some just guess a negative letter-spacing, which holds for one font at one size.
05How much it moves
I wanted a number. We took fifteen of the most popular variable fonts on Google Fonts, set six navigation labels and a sentence at sixteen pixels with HarfBuzz, which is the shaping engine Chrome and Firefox use, and compared weight 400 with 700. On median, the labels got 4.8 percent wider. The worst was over nine.
06Font by font
And it really depends on the typeface. Work Sans and Roboto barely move, about one percent, so picking a font like that is a perfectly good fix on its own. Inter and Montserrat sit around five. Open Sans and Rubik grow nearly eight percent. That’s two to nine pixels per label.
07Grade
Type designers dealt with this a long time ago. There’s an axis called grade. It changes how thick the strokes are without changing how wide the letters are. Google’s glossary says it was originally conceived for printed newspapers, to calibrate output from different presses. We checked it in Roboto Flex. Across the whole grade range, the width of our labels changed by zero.
08Who ships grade
So which fonts have it? I went through the whole Google Fonts catalogue. Of five hundred and forty-four variable families with a weight axis, five have grade. Five. But ninety-six have a width axis, and that turns out to matter.
09What it looks like
Here’s the same word, blown up four times, in Roboto Flex. The red line is where Regular ends. Plain bold runs past it. Bold with tightened letter-spacing, which is what our library does, holds the line, but look at the t and the i: it’s tight. Bold that’s narrowed with the width axis holds the line and keeps its spacing. And grade holds the line and looks the most natural of all.
10The order
So if you remember one thing: reach for grade first. If the font doesn’t have it, narrow it with the width axis. And if it has neither, tighten the spacing, by exactly the amount you measured.
11How hoverBoldly works
That last case is why we built hoverBoldly. It’s ours, and it’s free. And it isn’t a new idea: in 2013 the type designer Hrant Papazian called it fixed-offset, two weights made the same width by a set amount of tracking. It measures the text at both weights in a canvas, off the page. It divides the extra width by the number of characters. It tightens the letter-spacing by that much, on top of any spacing you already set. And it bumps the weight at the same moment. It’s built for text in a paragraph, where you can’t reserve space the way the CSS trick does.
12Does it hold?
We tested it in Chrome, on the shipped code. Mixed-case labels: plain bold moved a median of three and a half pixels. With hoverBoldly, zero, and at most two hundredths of a pixel. Tracked uppercase labels were the interesting one. Our old version made them worse, up to twenty-three pixels, because it threw away your letter-spacing. The fixed version holds them to under a fifth of a pixel. And sweeping a pointer across a menu, Chrome logged four to eight layout shifts with plain bold, and none with ours.
13Demo
Here it is on the site. Every word you hover goes bold, and the paragraph doesn’t reflow.
14Where it falls short
A few things it doesn’t do. It needs a variable font with a weight axis. Tightened bold is visibly tighter than real bold, so if your font has grade or width, use those. Keyboard focus works in the default mode, and you should still keep a focus ring. And for a nav bar, the CSS copy trick is often the simpler choice.
15Three asks
Three asks. Type designers: ship a grade axis, or at least a width axis, in your web families. Designers and developers: let the weight change and leave the width alone; grade first, width second, spacing last. And the CSS working group: there are two open issues right now, one on synthetic bold and one on a bold-text preference, and the minutes already mention grade. I’d love to see them grow into a way to ask for emphasis without movement.
16Close
Weight changes emphasis. Width changes layout. Thanks for watching. Everything’s at hoverboldly.com.
17Who we are
We’re Overpunch. We’ve built websites for type foundries for over fifteen years, and we’re building Typetin, a storefront for independent foundries, with a waitlist at typetin.com. hoverBoldly is one of twenty type tools we make for the web.