Count Indicator
A count indicator shows the user’s current position within a sequence as plain text — “1 of 6” — paired with previous and next icon buttons.
Ready to use
The Count Indicator (also known as pagination read-out) shows the user’s current position within a sequence as plain text — “1 of 6” — paired with prev/next icon buttons. It’s commonly used in image carousels, galleries, step-by-step flows, or small collections where space is limited and full pagination controls are unnecessary.
Anatomy
Section titled “Anatomy”- Page indicator
- Label
- Previous
- Next
When to use it
Section titled “When to use it”Use the Count Indicator when:
- Navigation is simple and sequential — image sliders, onboarding screens, galleries.
- The current position needs to be clear and the boundaries communicated by disabled icon buttons.
Avoid the Count Indicator when:
- The collection is large or complex and needs full pagination.
- Subtle colour shifts are the only cue at the boundaries — disable the prev/next buttons so the chevron shape carries the signal.
Properties
Section titled “Properties”Variant
Two variants tuned to the surface beneath: On Solid for default page surfaces (bare text label, no backdrop) and On Image for overlays (label picks up a backdrop and border so the text stays legible against busy backgrounds). Both share the same height and inline padding; only fill and border change.
Scheme
Neutral or Contrast. The foreground tokens flip via the CDS scheme — on a light surface (default), the label uses the neutral foreground; on a dark surface (.is-contrast on the wrapper), it flips to contrast — and the icon buttons follow via the same cascade.
Icon buttons
Prev and next are standard medium Icon Buttons. Their height feeds into the label height so the three pieces align. At the start and end of the sequence, the relevant button is disabled to communicate the boundary.
Platform considerations
Section titled “Platform considerations”Desktop
The wrapper sits inline at its natural width. Use the On Image variant only when the indicator overlays imagery; on plain surfaces the bare label reads more cleanly.
Tablet
Same layout as desktop. Keep the icon button size consistent with surrounding controls so the indicator doesn’t feel out of place.
Mobile
Stack the indicator with its content above or below imagery. The medium icon button stays well above the 44 px touch minimum at this size.
Best practices
Section titled “Best practices”Make sure both the count and the disabled state of the chevrons carry meaning.
Do
Pair the indicator with simple, sequential content, disable the prev/next icon buttons at the ends so the chevron shape carries the boundary cue, and reach for the Contrast scheme when the wrapper sits on dark imagery so foreground colours flip cleanly.
Don't
Don’t use the Count Indicator for large or complex collections (full pagination or a different pattern fits better), and don’t rely on colour change alone to signal the boundary — disable the buttons so the cue is unmistakable.
Content guidelines
Section titled “Content guidelines”The label is a position read-out, not a sentence — keep it to the bare “current of total” format (“1 of 6”). Localise the connecting word (“of” / “/” / “sur”) through the same string used elsewhere in the product so the announcement stays consistent for screen-reader users.
Styles
Section titled “Styles”<div class="tng-count-indicator"> <span class="tng-count-indicator-label">1 of 6</span> <button class="tng-icon-button is-md" aria-label="Previous"> <i class="tng-icon icon-chevron-left" aria-hidden="true"></i> </button> <button class="tng-icon-button is-md" aria-label="Next"> <i class="tng-icon icon-chevron-right" aria-hidden="true"></i> </button></div>The wrapper holds a label pill (.tng-count-indicator-label) and any combination of .tng-icon-button siblings. The label may sit at the start, in the middle, or at the end of the run; the wrapper applies the right inter-element spacing based on position. The label height matches the icon-button size that’s beside it.
Variants
Section titled “Variants”On Image
Section titled “On Image”Add .on-image to the wrapper so the label picks up a backdrop and border. Pair with .is-contrast on dark imagery so the foreground (and icon buttons) flip to contrast tokens.
<div class="tng-count-indicator on-image on-contrast"> <span class="tng-count-indicator-label">1 of 6</span> <button class="tng-icon-button is-md" aria-label="Previous"> <i class="tng-icon icon-chevron-left" aria-hidden="true"></i> </button> <button class="tng-icon-button is-md" aria-label="Next"> <i class="tng-icon icon-chevron-right" aria-hidden="true"></i> </button></div>The label height tracks the sibling icon-button size — drop .is-md, .is-sm, or .is-xs on the buttons and the label follows. Default is .is-sm (32px) when the icon-button class carries no size modifier.
<div class="tng-count-indicator"> <span class="tng-count-indicator-label">1 of 6</span> <button class="tng-icon-button is-sm" aria-label="Previous"> <i class="tng-icon icon-chevron-left" aria-hidden="true"></i> </button> <button class="tng-icon-button is-sm" aria-label="Next"> <i class="tng-icon icon-chevron-right" aria-hidden="true"></i> </button></div>Arrangements
Section titled “Arrangements”The label is optional, and may sit at the start, in the middle, or at the end of the wrapper. Spacing adapts to the position automatically.
<div class="tng-count-indicator"> <button class="tng-icon-button is-md" aria-label="Previous"> <i class="tng-icon icon-chevron-left" aria-hidden="true"></i> </button> <button class="tng-icon-button is-md" aria-label="Next"> <i class="tng-icon icon-chevron-right" aria-hidden="true"></i> </button></div><div class="tng-count-indicator"> <button class="tng-icon-button is-md" aria-label="Previous"> <i class="tng-icon icon-chevron-left" aria-hidden="true"></i> </button> <span class="tng-count-indicator-label">1 of 6</span> <button class="tng-icon-button is-md" aria-label="Next"> <i class="tng-icon icon-chevron-right" aria-hidden="true"></i> </button></div><div class="tng-count-indicator"> <button class="tng-icon-button is-md" aria-label="Previous"> <i class="tng-icon icon-chevron-left" aria-hidden="true"></i> </button> <button class="tng-icon-button is-md" aria-label="Next"> <i class="tng-icon icon-chevron-right" aria-hidden="true"></i> </button> <span class="tng-count-indicator-label">1 of 6</span></div>The count indicator pairs a live status label (“1 of 6”) with previous / next controls, so it has no single WAI-ARIA interaction pattern of its own — it leans on live region behaviour for the count and native <button> semantics for the controls, and meets WCAG 2.1 AA. An accessible count indicator announces the current position as it changes, names each control, and exposes the boundaries of the sequence — so the user’s place is clear whether they see it, hear it, or tab through it.
For designers
Section titled “For designers”- The label and the icon buttons — including their hover, focus, and disabled states — must maintain accessible contrast on every supported surface, including the
on-imagevariant placed over photography. Source: WCAG 1.4.3 Contrast (Minimum). - The disabled (boundary) state must never be conveyed by colour alone — the chevron’s shape already carries meaning; pair it with helper text where ambiguity remains. Source: WCAG 1.4.1 Use of Color.
- Focus styles must stay visible, meet contrast requirements on every supported surface, and be clearly distinguishable from hover. Source: WCAG 2.4.7 Focus Visible.
- Use semantic colour tokens (e.g.
foreground/neutral/default) rather than fixed values, so the component adapts correctly across themes and surfaces.
For developers
Section titled “For developers”The wrapper (.tng-count-indicator) is presentational, not a landmark — the landmark belongs on the surrounding region (carousel, gallery, paginated list) the indicator sits inside. Promote the wrapper itself only when that context isn’t already labelled. The controls are native <button> elements, so they carry their own semantics and keyboard operation for free; keep the chevron icons out of the accessibility tree with aria-hidden="true". Interactive targets must be at least 44 px high for comfortable touch use — comfortably clearing the WCAG AA minimum. Source: WCAG 2.5.8 Target Size (Minimum). Each element’s role, accessible name, and state are in the Labelling elements section below.
Labelling elements
Section titled “Labelling elements”Give every element the role, name, and state assistive technology needs.
Wrapper
Presentational by default — it takes no role. When the surrounding context isn’t already labelled, promote it to a landmark so the cluster is discoverable as a unit: <nav aria-label="Search results pages"> for pagination, or role="group" with an aria-label (e.g. "Gallery navigation") for a gallery.
Label
The count read-out (.tng-count-indicator-label). Add aria-live="polite" so assistive technology announces the new position as the user navigates; its text (“1 of 6”) is the accessible status.
Navigation buttons
Each icon-only <button> takes its accessible name from aria-label (e.g. "Previous item" / "Next item"), with the chevron marked aria-hidden="true". At the ends of the sequence, add the native disabled attribute to the boundary button rather than hiding it — screen-reader users discover the limit that way, and the focus order stays stable.
Source: WCAG 4.1.2 Name, Role, Value.