---
title: "Negative numbers in a financial table"
description: "Use parentheses instead of a minus sign, the real minus where a sign belongs, and a column that stays aligned when the sign changes. Almost nobody implements the third rule."
canonical: "https://lopifi.com/docs/guides/negative-numbers-in-financial-tables"
---

# Negative numbers in a financial table

> Use parentheses instead of a minus sign, the real minus where a sign belongs, and a column that stays aligned when the sign changes. Almost nobody implements the third rule.

Source: https://lopifi.com/docs/guides/negative-numbers-in-financial-tables
Part of: Lopifi — Planned: US GAAP books on autopilot, checked by a CPA (https://lopifi.com)

---

# Negative numbers in a financial table

Use parentheses instead of a minus sign, the real minus where a sign belongs, and a column that stays aligned when the sign changes. Almost nobody implements the third rule.

---

## Which convention, where

| Context | Format | Why |
|---|---|---|
| Statements, ledgers, tables | `(1,234.00)` | The accounting standard. The reader is scanning a column, and parentheses stand out in peripheral vision where a leading hyphen doesn't. |
| Deltas, KPIs, inline prose | `−$1,234.00` | A delta is a change, not a balance. On its own, an explicit sign reads faster than a bracket. |

Both are colored `--negative`, and **neither depends on color**. The parens and the sign carry the meaning, so the interface survives a grayscale print and red-green color blindness. The [showcase](/showcase/statements) has a grayscale toggle in its header if you want to check.

Don't mix the two conventions in one table. A column where some negatives are bracketed and some are signed reads as two different measurements.

## Use the real minus

`−` is U+2212 MINUS SIGN. `-` is U+002D HYPHEN-MINUS, a different glyph: shorter, lower, and not the same width as `+`. In a column of deltas, `+12.4%` and `-12.4%` won't line up.

`Intl` won't save you. `en-US` and most locales emit U+002D, and only a few (Swedish, Finnish and others) emit U+2212. Swap the sign after formatting, or use `currencySign: "accounting"` and parentheses. The same bug shows up when someone hand-builds the string:

```ts
`-${format(Math.abs(value))}`   // hyphen-minus. Wrong width, breaks the column.
```

## The alignment problem

This is the one teams skip. In a right-aligned column mixing `1,234.00` and `(1,234.00)`, the closing paren pushes the digits about 4px left, and the decimal points stop lining up. It's subtle enough to pass review and obvious enough to look amateur next to a printed statement.

Three fixes, best first:

**1. Reserve the paren column.** Render an invisible `)` on positive values.

```tsx
<span aria-hidden className="invisible">)</span>
```

Cheapest, works everywhere, and keeps copy-paste clean if you strip `aria-hidden` content on copy.

**2. Grid the cell.** `display: grid; grid-template-columns: auto 1fr auto;` for open paren, figure, close paren. The sturdiest option for mixed content.

**3. Pad the cell.** `padding-right: 1ch` on positives. Only correct under `font-variant-numeric: tabular-nums`, where `1ch` is a real fixed unit.

Treat the sign in a delta column the same way. Reserve the slot so a list of changes stays aligned even when some rows are unchanged.

## Sign is not sentiment

A negative number isn't bad news. A `−4.2%` change in burn is good; a `−4.2%` change in revenue isn't. Coloring by sign is how a dashboard shows cheerful green on a cost overrun.

So polarity is an explicit prop:

```tsx
<Delta value={{ amount: 8200, currency: "USD" }} polarity="inverted" />
// ↑ +$8,200.00 — colored negative, because up is bad for this metric
```

`standard | inverted | neutral`, set per metric. There's no defensible default, so the component doesn't pick one for you.

## Zero is not a small negative

A true zero in a statement renders as an em dash (`—`), which means *computed, and nil*. A blank cell means *not applicable here*. `n/a` means *we don't have this*. None of them is `$0.00`. In transactional tables and inputs, where a figure is typed instead of read as a total, `$0.00` is fine. See [formatting money](https://lopifi.com/md/docs/guides/format-money-in-react).

---

## Where this is implemented

- [`Money`](/components/money): `accounting` and `statement` modes, and the reserved paren column
- [`Delta`](/components/delta): the polarity contract, and the reserved sign slot
- [`StatementRow`](/components/statement-row) and [`StatementTable`](/components/statement-table): negatives and rule lines together
- [`VarianceCell`](/components/variance-cell): where a signed number and a polarity meet a budget
- [Statements, running](/showcase/statements): flip a value negative and watch the column hold
- [Numerics](https://lopifi.com/md/docs/foundations/numerics#negative-alignment): the full rule, with the three fixes ranked
- [Color](https://lopifi.com/md/docs/foundations/color): why the sign never depends on hue alone
