Counter annotates labels—tabs, nav items, filters—with a numeric tally. It helps operators prioritize work ("how many open incidents?") without opening each section. Treat counters like platform notification badges: small, legible, and present only when the number genuinely changes behavior.
- Tab or menu labels where the count changes operator behavior (queues, unread, failures).
- Filters where total active items informs whether to engage ("Errors (4)").
- Supplementary emphasis when the number is secondary to the label—use
Subtle styling.
- Unread counts pinned over the control they belong to—use
Error styling with a positioning className.
- Primary dashboard metrics—use typographic emphasis,
Pill, or charts.
- Counts that update many times per second—debounce or omit to avoid visual noise and accessibility chatter.
- Binary state—use a
Badge or an icon with text.
- Format counts per locale. Use localization helpers; don't concatenate strings.
- Cap display when numbers explode ("99+") if a product standard defines it, and apply the rule consistently across dispatch.
- Zero. Pick one pattern per surface—hide, show "0", or gray out—and stick to it.
- Loading. Avoid flashing random values. Use a skeleton on the row or defer rendering the counter until data resolves.
Do
- Show counters only when the number changes decisions. Otherwise omit.
- Sync counts with server truth on a deterministic interval or websocket update policy.
Don't
- Use counters as the only error indicator—pair with
Callout or row-level state.
- Stack multiple counters on one label without designer review.
The hosting control's accessible name includes the count when the count matters ("Chat, 3 unread"), or uses aria-describedby consistent with TabMenu and Tabs. Avoid announcing rapid count changes in live regions. See Accessibility for the full contract.
- Tab menu for in-page tab strips with counts.
- Tabs for panel switches with optional counters on triggers.
- Badge for status labels rather than quantities.