Pagination
How the Pagination works with a keyboard and assistive tech, and where it stands against WCAG 2.2 AA.
Pagination is a <nav> of ordinary buttons, a native select and a small form, so the browser supplies most of the keyboard. The component names each page, marks the current one, and says the new page out loud after a move. It is held to WCAG 2.2 AA for contrast, focus and target size.
Keyboard#
Moves through the arrows, the page cells and the jump control in reading order. Disabled arrows and the ellipsis are skipped.
Moves back the same way.
Goes to the focused page, or to the number typed in Go to.
Goes to the focused page, or opens the page select.
In the page select, moves through the pages. Up moves back.
In Rows per page, chooses the next size, wrapping. Left goes back; Up and Down do the same.
Semantics#
<nav aria-label="Pagination">A navigation landmark. Name it for what it pages, such as Invoices pagination, when there are two on a page.
Alwaysaria-current="page"Announced as the current page; the dark or ringed cell only echoes it.
Current cellaria-label="Page 4"Each number is a <button> named Page 4. In bar 02 the last cell is named Last page, 26.
Page cellsaria-labelFirst page, Previous page, Next page, Last page. Text arrows use their visible label.
Icon arrowsdisabledFirst and Previous on page 1, Next and Last on the last page.
At an endaria-hidden="true"The … cell is decorative. The visible Page 4 of 26 is hidden because the live region says the same.
Ellipsis, statusaria-live="polite"A hidden region that reads Page 4 of 26 after each move.
Alwaysrole="radiogroup"One tab stop, arrow keys move the choice, each option is a radio with aria-checked.
Rows per pageColour contrast#
Every variant and state has to meet WCAG 2.2 Level AA. Measure the colours as they land on screen: a translucent hover or press wash over whatever sits behind it.
Page number · Default, Hover, Current
The 14px Medium number against the cell's fill in every appearance and state, with hover washes laid over the bar behind. Group 05's cells sit on a #f2f2f2 pill, so they are measured on that.
WCAG 1.4.3 Contrast (Minimum) ↗Arrows and buttons · Default, Hover
Flat arrows are #2a2a2a on #f2f2f2, 12.82:1, and 12.04:1 on hover. The dark arrows and the Go button are white on #2a2a2a, 14.35:1, and 11.37:1 on hover.
WCAG 1.4.3 Contrast (Minimum) ↗WCAG 1.4.11 Non-text Contrast ↗Status and lead words · Always
The Page 4 of 26 status is #8f8f8f on white, 3.23:1, under 4.5:1. Lead words such as Page and Go to step up to #2a2a2a.
WCAG 1.4.3 Contrast (Minimum) ↗Current page · Current
Fill Black inverts the cell, and Outline and Fill White add a ring or a white face. Pair the look with aria-current, and keep the status text visible, so position doesn't rest on the fill alone.
WCAG 1.4.1 Use of Color ↗WCAG 1.4.11 Non-text Contrast ↗Focus indicator · Focus visible
A 2px #1a6ef8 ring with a white gap, 4.54:1 against white, and further out on the dark and skeuomorphic buttons so it clears their own stroke.
WCAG 1.4.11 Non-text Contrast ↗WCAG 2.4.13 Focus Appearance ↗Disabled · Disabled
Disabled arrows and cells, #cbcbcb on #f2f2f2, are exempt.
WCAG 1.4.3 Contrast (Minimum) ↗Measured contrast#
Number against the cell in each state, with translucent fills laid over the white bar, or over the #f2f2f2 pill and Rows per page bar where they sit. All 15 pairs reach their minimum.
Motion#
- Cell and button fills change over 120ms and at once under prefers-reduced-motion.
- Moving to a new page does not scroll or animate the bar. Move focus or scroll to the top of the results deliberately, not by animation.
Checklist#
After a page change, keep focus where it was or move it to the top of the new results. Don't let it drop to the page body.
Darken the status text: #8f8f8f is 3.23:1. #6d6d6d reaches 5.17:1.
Targets clear WCAG 2.5.8: cells are 28 to 36px tall and at least 36px wide, arrows 48px, Rows per page options 36px.
The Go to field takes digits only and says the range in its hidden hint. Show an error if the number is out of range; the preview ignores it silently.
Narrow, the bar wraps by group instead of scrolling. Keep the arrows on the same row as the cells where you can.
Name a second Pagination on the same page differently, so the two landmarks can be told apart.
