# Use Tabular Numbers for Data

**MUST** · **ID:** `content-ibelick-tabular-nums` · **Category:** content
**Source:** [@Ibelick](https://www.ui-skills.com/)
**Interactive version:** https://ui-guides-agent-rules.netlify.app/principles/content-ibelick-tabular-nums

> MUST: Use tabular-nums (font-variant-numeric: tabular-nums) for numerical data in tables, counters, and prices. Numbers align in columns without jumping.

Always use tabular-nums for numbers in tables and data displays for proper alignment

From the Typography constraints in ibelick's baseline-ui skill (the Tailwind `tabular-nums` utility maps to font-variant-numeric: tabular-nums). Proportional figures have varying widths, so columns of numbers misalign and counters jitter as they tick. Tabular figures share one advance width, so data tables, prices, and numeric lists line up.

## Bad — do not do this

`content-ibelick-tabular-nums-bad`

```tsx
export function IbelickTabularNumsBad() {
  const data = [
    { name: 'Product A', price: 1.99, qty: 111 },
    { name: 'Product B', price: 24.50, qty: 8 },
    { name: 'Product C', price: 199.00, qty: 42 },
  ];

  return (
    <div className="space-y-4">
      <table className="w-full text-sm">
        <thead>
          <tr className="border-b">
            <th className="text-left py-2">Product</th>
            <th className="text-right py-2">Price</th>
            <th className="text-right py-2">Qty</th>
          </tr>
        </thead>
        <tbody>
          {data.map((row) => (
            <tr key={row.name} className="border-b">
              <td className="py-2">{row.name}</td>
              <td className="text-right py-2">${row.price.toFixed(2)}</td>
              <td className="text-right py-2">{row.qty}</td>
            </tr>
          ))}
        </tbody>
      </table>
      <p className="text-xs text-destructive">
        Proportional numbers - columns don't align properly
      </p>
    </div>
  );
}
```

## Good — do this

`content-ibelick-tabular-nums-good`

```tsx
export function IbelickTabularNumsGood() {
  const data = [
    { name: 'Product A', price: 1.99, qty: 111 },
    { name: 'Product B', price: 24.50, qty: 8 },
    { name: 'Product C', price: 199.00, qty: 42 },
  ];

  return (
    <div className="space-y-4">
      <table className="w-full text-sm">
        <thead>
          <tr className="border-b">
            <th className="text-left py-2">Product</th>
            <th className="text-right py-2">Price</th>
            <th className="text-right py-2">Qty</th>
          </tr>
        </thead>
        <tbody>
          {data.map((row) => (
            <tr key={row.name} className="border-b">
              <td className="py-2">{row.name}</td>
              <td className="text-right py-2 tabular-nums">${row.price.toFixed(2)}</td>
              <td className="text-right py-2 tabular-nums">{row.qty}</td>
            </tr>
          ))}
        </tbody>
      </table>
      <p className="text-xs text-success">
        tabular-nums - numbers align perfectly in columns
      </p>
    </div>
  );
}
```

## References

- [baseline-ui (skill source)](https://github.com/ibelick/ui-skills/blob/main/skills/baseline-ui/SKILL.md)
- [font-variant-numeric MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Properties/font-variant-numeric)
