Count badge — accessibility

Keyboard

  • Not focusable and not interactive: it is a <span> that labels something else.
  • When it sits inside a tab or a nav item, that host is the control and takes the tab stop; the count travels with it.

ARIA

  • No role and no label of its own. The badge is read as part of the thing it annotates — Úkoly 12 — which is the intended reading.
  • It must therefore never be the only place the meaning appears: 12 alone says nothing, so the heading next to it has to carry the noun.
  • Nothing announces a change in the number. A count that goes up in the background is silent, and accent (unread) is exactly the case where that matters.
  • A count that is a problem must say so in words; there is no longer a tone that carries it.

Focus

  • Nothing focusable, so no ring of its own. Inside a tab, the tab's own foundation ring applies.

Contrast

Computed from packages/ui/src/tokens/tokens.css:

  • Default: --fg-secondary on --surface-75 — 3.80:1 light, 6.53:1 dark. Below AA for normal text in the light theme, though it is 11px bold on a bordered ground, and the 1px --border gives the shape its own definition rather than relying on the fill.
  • .accent: --accent-ink on --accent-tint — 4.58:1 light, 5.37:1 dark. AA.
  • .alert was removed on 5 Sep 2026 precisely because it failed here: white on --critical is 3.91:1 in both themes, below AA on the variant meant to shout.

Known limits

  • The default tone is under AA in the light theme; it leans on the border to stay legible.
  • Changes are never announced.
  • The 1px geometry drift between ds.css and ds/section-block.css means the same badge is drawn at two sizes in different parts of the app.

Source: docs/status/count-badge.a11y.md · GitLab