Skip to content
RU
Scale
Density
Theme
Accent

Navigation

Pagination

Going through the pages of a long list. Every page is an address of its own, so these are links rather than buttons.

The component
Markup
<nav aria-label="Pages">
  <ol class="inst-pager">
    <li><a class="inst-pager-item" href="#" aria-disabled="true">Back</a></li>
    <li><a class="inst-pager-item" href="#" aria-current="page">1</a></li>
    <li><a class="inst-pager-item" href="#">2</a></li>
    <li><a class="inst-pager-item" href="#">3</a></li>
    <li><span class="inst-pager-gap">…</span></li>
    <li><a class="inst-pager-item" href="#">24</a></li>
    <li><a class="inst-pager-item" href="#">Forward</a></li>
  </ol>
</nav>

Contract

A pager is an <ol> inside a <nav aria-label>: the pages are ordered, and the order is part of the meaning. The library removes the markers and the indent of the list itself, so no wrappers are needed.

What Required Why
A <nav> + an aria-label yes A landmark of its own: the screen already has a side navigation and breadcrumbs
An <ol> with <li> yes The pages are ordered
An aria-current="page" yes The only source of the current page. There is no class for it
An aria-disabled="true" yes, at the edge of the range A link has no disabled — the ARIA attribute is the only truthful one here

inst-pager-gap is a <span> rather than a link: an ellipsis marks a gap rather than a page. It stays inside an <li> so that the list does not lose its structure.

Accessibility

The keyboard Native links: Tab traverses, Enter goes. Nothing is intercepted
The tap target At least --control-h-sm on both axes — a square rather than a narrow rectangle. At density compact it drops to 22px, below the 24px threshold of WCAG 2.5.8: keep a pager out of compact
The current page It carries an aria-current, a fill and a border: colour is not the only carrier
Unavailability An aria-disabled is spoken and keeps the focus, unlike removing the link
Contrast The label is --text-secondary, the ellipsis --text-faint — it is decoration rather than data
Print A pager is not printed: on paper there are no pages left

States

Example
Markup
<nav aria-label="An example of the states">
  <ol class="inst-pager">
    <li><a class="inst-pager-item" href="#" aria-disabled="true">Back</a></li>
    <li><a class="inst-pager-item" href="#">7</a></li>
    <li><a class="inst-pager-item" href="#" aria-current="page">8</a></li>
    <li><a class="inst-pager-item" href="#">9</a></li>
  </ol>
</nav>
State How it is set What happens
current aria-current="page" --surface-selected, --accent-text, a border of --accent-border by an inner shadow, --weight-medium
unavailable aria-disabled="true" An opacity of 0.5 and the mouse removed. A link has no disabled — the ARIA attribute is the only truthful one here
hover :hover --surface-hover and the full colour of the label

An aria-disabled does not remove the link from the order of traversal — it stays reachable from the keyboard and is spoken as unavailable. Intercepting the press belongs to the application layer: only the mouse is removed.

API

Classes
NameWhat it does
class
inst-pagerThe list of pages. Put on an <ol>; it wraps across the width
inst-pager-itemA page or an arrow. A square no smaller than --control-h-sm
inst-pager-gapThe ellipsis in the place of a skipped range. Not a link
Tokens
NameValueWhere from
token
--control-h-sm24pxbase +14: density · scale
--radius-sm6pxbase +4: scale
--space-24pxone across every cell
--space-36pxone across every cell
--text-xs0.78125rembase +4: scale
--weight-medium600one across every cell
--hairline1pxbase +1: screen
--surface-hoverlight-dark(oklch(0 0 0 / 0.035), oklch(1 0 0 / 0.045))one across every cell
--surface-selectedcolor-mix(in oklab, var(--a-4) 14%, transparent)one across every cell
--accent-textlight-dark(var(--a-5), var(--a-3))base +1: theme
--accent-borderlight-dark(var(--a-4), var(--a-3))one across every cell
--text-secondarylight-dark(var(--n-9), var(--n-5))one across every cell
--text-faintlight-dark(var(--n-7), var(--n-7))one across every cell

Why the kit works this way — the constitution · Open source under MIT, github.com/keshon/instrument