back

Tabular numbers

One of the simplest typography fixes on the web is also one of the easiest to miss: tabular numbers.

By default, many fonts use proportional numerals. That means 1 is narrower than 8, 0 is wider than 7, and a number changing from 19 to 20 can subtly shift the layout around it.

Tabular numbers fix that by giving every numeral the same width.

.stat {
  font-variant-numeric: tabular-nums;
}

That is enough to make a surprising number of interfaces feel more stable.

Where it matters

There are two cases where I almost always want tabular numbers.

1. Numbers in columns

Tables, dashboards, finance UI, analytics panels, invoice totals, leaderboards. If users are scanning down a column of values, aligned digits are easier to compare than proportional ones.

td[data-type="number"] {
  font-variant-numeric: tabular-nums;
}

This gets more important as values get longer. 1,240, 98, and 12,004 are much easier to scan when each digit occupies the same width.

2. Numbers that update in place

Timers, countdowns, scoreboards, OTP inputs, live metrics, price tickers, download progress. If the number changes and the text around it should stay visually still, tabular numbers help immediately.

Without them, the interface can feel like it is wobbling for no good reason.

.timer,
.price,
.metric-value {
  font-variant-numeric: tabular-nums;
}

This is one of those details that users will not name, but they will feel it.

Where it usually does not matter

Not every number needs it.

If the number is sitting inside a paragraph, article body, or sentence where alignment is not doing any work, proportional numerals often look more natural. Tabular numbers are a utility, not a default for all text.

That is why I usually apply them narrowly:

Tailwind

If you are using Tailwind, you do not need custom CSS for this. Use tabular-nums.

<span class="tabular-nums">01:59</span>

Small property, high payoff.

If a number needs to line up or stay still while it changes, it probably wants tabular numbers.