C-24 · Components · Navigation
All elements · Pagination on the Components page
Last checked 2026-10-22 · Awaiting approval · Accessibility tests
Approve Pagination
Approving as
| Axis | Values |
|---|---|
mode |
pages · cursor (prev/next only) · load-more |
__page[aria-current=page] · __ellipsis · __info ·
__size
|
parts |
Guidance
When to use
- Page through a large result set in a table or list when users need to jump to a known page or report "page 4".
- Use cursor mode (Previous and Next only) when the server cannot count results or pages shift as data changes.
- Use load-more mode in feeds and side lists where users scan forward and rarely go back.
-
Pair the page buttons with
__info("Showing 21–40 of 312") and__size(rows per page) under a data table.
When to consider something else
- When the rows sit in a Data grid with virtual scrolling, let the grid scroll instead of paging. See DataGrid.
- When steps of a process are being tracked rather than pages of data, use Step indicator. See StepIndicator.
- When the collection fits on one screen, show it all and drop pagination.
Usability
- Show the total and the current range in
__infowhen the server knows them. - Keep the first and last page visible and collapse the middle with
__ellipsis. - Keep the selected rows-per-page value for the user across sessions.
- Keep sort, filters and selection when the page changes, and say if selection does not carry across pages.
- In load-more mode, say how many are loaded of how many, as the specimen does.
- Don't use load-more where users need to return to an exact position.
- Don't remove the Previous button on page 1; disable it so the layout stays stable.
- Don't reset the user to page 1 when they change something unrelated, such as a column width.
Accessibility
Keyboard
| Keys | Action |
|---|---|
| Tab / Shift+Tab | Moves through Previous, each page button, Next and the rows-per-page select. |
| Enter or Space | Goes to the focused page, or loads more. |
| Arrow Up / Arrow Down | Changes the rows-per-page value in the native select. |
Roles and names
-
Page and cursor modes sit in a
navwith anaria-label, such as "Pagination"; use a distinct label when a page has more than one. - The current page button carries
aria-current="page". -
Previous and Next icon buttons have
aria-label="Previous"andaria-label="Next"; the chevrons arearia-hidden. - Page buttons should be named "Page 3" by the binding, since a bare number is unclear out of context.
-
The
__ellipsisis text, not a control; hide it witharia-hiddenor give it no role. -
The rows-per-page
selecthas anaria-label; at the ends, Previous or Next isdisabled.
Focus
- After a page change, focus stays on the page control the user pressed, so they can keep paging.
- After load more, the binding must move focus to the first new item or keep it on the button, never lose it to the body.
- All controls show the shared focus ring.
Other requirements
-
The binding must announce the new range (for example, update
__infoinside a polite live region) because new rows load without a page reload (4.1.3). - Page buttons are at least 2rem square, meeting 2.5.8.
- The current page is shown by fill and weight, not color alone, and its fill needs 3:1 (1.4.1, 1.4.11).
- At 320px width (1.4.10) drop to Previous, current page and Next rather than overflow.
Test your implementation too. This guidance covers the element as specified here. How a screen composes it (labels, order, announcements) still needs its own keyboard and screen reader check.
Accessibility tests
Passed the gate (run 358b316 on 2026-10-22): no finding in any theme. Awaiting a person’s approval of the checklist below.
| Area | Automated | A person checks |
|---|---|---|
| General | Passed | Color is never the only cue, text alternatives say the same thing as the graphic, and the element reads the same in the light and the dark theme. |
| Zoom | Passed | At 200% zoom, at 320 CSS pixels wide and with the WCAG text-spacing overrides, nothing is lost, clipped or overlapping. |
| Keyboard | Passed | Every row of the Keyboard table works, focus is always visible and never trapped, and the tab order follows the reading order. (3 rows) |
| Screen reader | Passed | With NVDA or JAWS on Windows and VoiceOver on macOS, names, roles and states are announced as Roles and names says, and changes are announced once. (6 items) |
Approving. When the checklist passes on the checked run, record it with
bun run a11y:approve -- pagination --by "Your name" and commit
a11y/approvals.json with the rebuilt pages.
All test status
Package
Consumers link one stylesheet, css/classic/index.css, which includes every element. The
files below are where this element is defined.
Latest updates
No recorded changes yet.