Why Letter-Spacing Variables Quietly Break in Figma

When I bound our text styles to variables, every style looked right in the panel. The tracking on the canvas was wrong, and Figma didn’t say a word.

The setup

Our text styles stored letter spacing as a percentage, the usual way: a tight negative value on large headings, a positive one on small uppercase labels. Percentages are handy because they scale. The same -2.5% tightens a big heading more than a small one.

To make the type system token-driven, I built a typography collection with variables for font size, line height, weight and letter spacing, and bound every text style to it.

What actually happens

A letter-spacing variable is a plain number. When you bind it, Figma switches the style’s unit from percent to pixels and takes the number literally. A heading set to -2.5% and bound to a variable holding -2.5 now renders -2.5px, not the roughly -0.6px it showed before.

I checked it twice, including with a non-zero value, to be sure it wasn’t a rounding fluke. Nothing errors. The style panel looks fine. Only the canvas is wrong.

The same heading with letter spacing as a percentage and as a bound variable read as pixels

Two more limits I ran into

  • Variable names can’t contain a period, so a token called letter-spacing/-0.24 is rejected. I named tracking tokens after the size step they pair with, not after their value.

  • Inter calls its weight “Semi Bold”, while Inter Display calls it “SemiBold”. One weight variable can’t serve both, so weights are split by font family.

The fix, and its cost

I converted every tracking value to its pixel equivalent: -1.5% at 16px became -0.24px, 10% at 12px became 1.2px. The styles render correctly again.

The cost is that tracking is now absolute. It no longer scales with font size, so if a heading’s size changes, its tracking token has to change too. I wrote that rule into the documentation, because a trade-off nobody knows about is just a future bug.

What I’d tell another design system team

  • Check every binding on the canvas, not in the panel.

  • Expect the unit to change when a value becomes a variable.

  • When the value can’t go in a token’s name, name it after where it’s used.

  • Write the trade-off down where the next person will look for it.

Tokens are only useful if they do what they say. A variable that silently changes its unit looks like a source of truth and isn’t one.