Type something to search...
What are tabular and proportional numerals?

What are tabular and proportional numerals?

Tabular numerals are digits that all have exactly the same width, so numbers stack neatly in columns and don't shift when they change. Proportional numerals have widths that suit each digit's shape, so a narrow 1 takes up less space than a wide 0 or 8, which gives a more even rhythm in running text. Many fonts contain both sets and use one as the default, often proportional in text-oriented fonts and tabular in some interface fonts. In CSS you switch between them with font-variant-numeric: tabular-nums or font-variant-numeric: proportional-nums, which enable the OpenType features tnum and pnum. The general rule is simple: use tabular figures wherever numbers are compared vertically or updated live, and proportional figures in sentences.

This choice sounds minor until you see a pricing table where the decimal points zigzag down the column, or a countdown timer whose digits wobble left and right every second. Both problems disappear with one line of CSS, yet they're common on dashboards, checkouts and admin interfaces. In this article you'll learn how the two styles differ, where each belongs, how to enable them reliably, how they combine with other numeral options, and how to align numbers properly in tables.

How the Two Styles Differ

Look at the number 1 in most fonts. It's a narrow shape. In a proportional set, it gets a narrow advance width, so "111" takes up much less space than "888". In a tabular set, the designer gives every digit the same advance width, usually the width of the widest digit, and adjusts the side spacing of narrow digits so they sit centred in their slot.

The result:

  • Proportional: Numbers look natural inside text, with even spacing between digits, but numbers with the same number of digits can have different widths.
  • Tabular: Every number with the same digit count has the same width, so columns align and changing values don't move neighbouring text, but a narrow 1 can look slightly isolated with extra space around it.

You can see the difference by measuring rendered widths in the browser:

<span id="p" style="font-variant-numeric: proportional-nums">1111</span>
<span id="t" style="font-variant-numeric: tabular-nums">1111</span>
<span id="t8" style="font-variant-numeric: tabular-nums">8888</span>
for (const id of ["p", "t", "t8"]) {
  const width = document.getElementById(id).getBoundingClientRect().width;
  console.log(id, width.toFixed(1));
}

In a font with both sets, the proportional "1111" is noticeably narrower than the tabular one, and the two tabular strings report the same width. If all three widths match, the font only has one style of figures.

Punctuation used with numbers, such as the decimal point, comma, colon and minus sign, may also have tabular widths in well-made fonts. That's what lets currency columns line up at the decimal point.

Where to Use Tabular Numerals

Use tabular figures whenever readers compare numbers by position or numbers change in place:

  • Tables of figures: Financial statements, price lists, sports results, specifications.
  • Dashboards and analytics: Metric cards, charts with numeric axes, key performance indicators.
  • Timers and clocks: Countdowns, stopwatches, media player progress.
  • Live counters: Stock prices, scoreboards, upload progress.
  • Forms and inputs: Numeric fields where users type amounts, card numbers or codes.
  • Invoices and receipts: Quantities, unit prices and totals in a column.
  • Code-like data: Version numbers, IP addresses and timestamps listed one above another.

Live Values That Don't Wobble

A timer is the clearest demonstration. With proportional figures, the text width changes as digits change, so anything next to it moves.

<p class="timer">Time left: <span id="clock">10:00</span></p>
.timer {
  font-variant-numeric: tabular-nums;
}
const clock = document.getElementById("clock");
let remaining = 600;

const tick = setInterval(() => {
  remaining -= 1;
  const minutes = String(Math.floor(remaining / 60)).padStart(2, "0");
  const seconds = String(remaining % 60).padStart(2, "0");
  clock.textContent = `${minutes}:${seconds}`;
  if (remaining === 0) clearInterval(tick);
}, 1000);

Remove the CSS rule and watch the label: the text shuffles slightly every second when a 1 appears or disappears. With tabular figures, it stays still.

Where to Use Proportional Numerals

Proportional figures belong in running text, where numbers are read as words rather than compared:

  • Body copy: "The survey had 1,174 responses in 2025."
  • Headlines and display text: Large numbers in a hero section look better with natural spacing.
  • Dates and addresses in prose: Anything read left to right in a sentence.
  • Marketing statistics: A big "11 million" in a callout can look gappy with tabular spacing.

In large display sizes, tabular spacing around 1 becomes very visible. If a headline contains a number with several 1s, check that it doesn't look like it has accidental spaces in it.

Enabling Them in CSS

The high-level property is font-variant-numeric:

body {
  font-variant-numeric: proportional-nums;
}

table,
.stat,
.price,
time {
  font-variant-numeric: tabular-nums;
}

font-variant-numeric has several independent groups of values, and you can set one from each group at the same time:

GroupValuesOpenType feature
Spacingproportional-nums, tabular-numspnum, tnum
Figure stylelining-nums, oldstyle-numslnum, onum
Fractionsdiagonal-fractions, stacked-fractionsfrac, afrc
Otherordinal, slashed-zeroordn, zero

A common combination for data is lining, tabular figures with a slashed zero, so 0 and O can't be confused:

.data {
  font-variant-numeric: lining-nums tabular-nums slashed-zero;
}

The low-level equivalent is:

.data {
  font-feature-settings: "lnum" 1, "tnum" 1, "zero" 1;
}

Prefer font-variant-numeric, because a later font-feature-settings rule on the same element replaces the whole list and can silently remove other features.

Utility Classes

If you use Tailwind CSS, the utilities map directly to these values:

<td class="tabular-nums text-right">1,204.50</td>
<p class="proportional-nums">Founded in 2011 with 11 staff.</p>

Tailwind also provides lining-nums, oldstyle-nums, slashed-zero, ordinal and diagonal-fractions, and they combine on one element.

Aligning Numbers in Tables

Tabular figures are only half of a well-aligned column. You also need the right alignment.

  1. Right-align numeric columns: Units line up with units, tens with tens. Left-aligned numbers are hard to compare.
  2. Use a consistent number of decimal places: Format values so every row has the same precision.
  3. Right-align the header too: A numeric column's header should sit above the numbers.
  4. Keep text columns left-aligned: Names and descriptions read better from the left edge.
<table class="figures">
  <thead>
    <tr>
      <th scope="col">Product</th>
      <th scope="col" class="num">Units</th>
      <th scope="col" class="num">Revenue</th>
    </tr>
  </thead>
  <tbody>
    <tr><td>Notebook</td><td class="num">1,120</td><td class="num">£11,200.00</td></tr>
    <tr><td>Pen set</td><td class="num">98</td><td class="num">£1,470.00</td></tr>
    <tr><td>Desk lamp</td><td class="num">41</td><td class="num">£1,845.50</td></tr>
  </tbody>
</table>
.figures {
  border-collapse: collapse;
  font-variant-numeric: lining-nums tabular-nums;
}

.figures th,
.figures td {
  padding: 0.5rem 0.75rem;
  border-bottom: 1px solid #ddd;
}

.figures .num {
  text-align: right;
}

Format Numbers Consistently

Let the browser format values with Intl.NumberFormat, so thousands separators and decimal places are always the same:

const gbp = new Intl.NumberFormat("en-GB", {
  style: "currency",
  currency: "GBP",
  minimumFractionDigits: 2,
});

console.log(gbp.format(11200));
console.log(gbp.format(1470));
console.log(gbp.format(1845.5));
£11,200.00
£1,470.00
£1,845.50

Combined with tabular figures and right alignment, the decimal points line up down the column.

Checking What Your Font Supports

Not every font contains both sets. If tabular-nums makes no visible difference, either the font's default figures are already tabular, or the font doesn't include the tnum feature.

  • Check the font's documentation or specimen: Many list their numeral options.
  • Inspect the file: Tools such as Wakamai Fondue show whether tnum and pnum are present.
  • Check after subsetting: Subsetting tools can strip features. With pyftsubset, keep them explicitly:
pyftsubset Inter-Variable.ttf \
  --unicodes="U+0000-00FF,U+20AC,U+2212" \
  --layout-features+=tnum,pnum,lnum,zero \
  --flavor=woff2 \
  --output-file=inter-latin.woff2

Default figure styles differ between fonts. Many interface fonts, including Inter and the system fonts on Apple platforms, use proportional figures by default and offer tabular figures as a feature. Some fonts, especially older ones designed with spreadsheets and reports in mind, default to tabular figures. Don't assume; test the font you're using.

If your font has no tabular figures and you can't change it, a monospaced font for numeric columns is a fallback, but it changes the look of the digits considerably. Choosing a font with proper figure options is the better long-term fix, which is worth considering when picking fonts for dashboards.


FAQ: Tabular and Proportional Numerals

Tabular numerals are digits designed with identical widths, so numbers with the same number of digits always take up the same space. That keeps columns aligned and stops changing values from shifting surrounding text.

Proportional numerals have widths that suit each digit's shape, so 1 is narrower than 0. They give a more natural, even rhythm in sentences and headings.

Use font-variant-numeric with the tabular-nums value. It enables the font's tnum feature. The font must contain tabular figures for it to have any effect.

No. Many proportional text and interface fonts include a tabular figure set. Only the digits, and sometimes related punctuation, become equal width while letters keep their normal spacing.

In tables, carts and anywhere prices are listed one above another, yes. A single price inside a sentence or a large marketing headline usually looks better with proportional figures.

Either the font's default figures are already tabular, or the font doesn't include the tnum feature, possibly because it was removed during subsetting. Check the font file or try a font known to support it.


Conclusion

Tabular and proportional numerals solve different problems. Tabular figures give every digit the same width, so columns align, prices line up at the decimal point, and timers and counters stay still as they update. Proportional figures give each digit its natural width, which reads more smoothly in sentences and looks better at large sizes.

Set proportional figures for body text, switch to font-variant-numeric: tabular-nums for tables, dashboards, timers and forms, right-align numeric columns, and format values consistently with Intl.NumberFormat. Check that your font actually contains both sets, and keep the features when you subset, so the CSS you write has something to switch on.

Share :

Related Posts

How to make typography accessible?

How to make typography accessible?

You make typography accessible by choosing clear typefaces, setting text in relative units so it scales with user preferences, giving it enough colou

Dive Deeper
What are the parts of a letterform?

What are the parts of a letterform?

A letterform is the shape of a single letter, and typographers break it down into named parts. The main ones are the stem (the main vertical

Dive Deeper
What are ascenders, descenders and the baseline?

What are ascenders, descenders and the baseline?

The baseline is the invisible line that letters sit on. Ascenders are the parts of lowercase letters that rise above the x-height, such as th

Dive Deeper