StartFoundationsComponentsContent

Pagination

Pagination splits a long list into numbered pages and moves between them. You decide which page numbers to show; the component draws them.

Stable Figma
OverviewUsageAPIAccessibility
1 3 4 5 20
<tk-pagination label="Search results">
  <tk-pagination-prev href="?page=3"></tk-pagination-prev>
  <tk-pagination-item href="?page=1">1</tk-pagination-item>
  <tk-pagination-ellipsis></tk-pagination-ellipsis>
  <tk-pagination-item href="?page=3">3</tk-pagination-item>
  <tk-pagination-item href="?page=4" current>4</tk-pagination-item>
  <tk-pagination-item href="?page=5">5</tk-pagination-item>
  <tk-pagination-ellipsis></tk-pagination-ellipsis>
  <tk-pagination-item href="?page=20">20</tk-pagination-item>
  <tk-pagination-next href="?page=5"></tk-pagination-next>
</tk-pagination>

Anatomy

Part What it is
tk-pagination a navigation landmark holding a list of the parts below
tk-pagination-item one page number: a link or a button; current marks the active page
tk-pagination-prev / tk-pagination-next a chevron to the previous or next page
tk-pagination-ellipsis "…" for skipped pages; not interactive

Every part is one cell, 40px by default. Pages and prev/next are one Tab stop each.

Pages

Each page and each prev/next control is a link or a button:

  • With href, it's a link. Use it when each page has its own URL.
  • Without href, it's a button that fires tk-page-select. Use it when the page changes in place, such as rows in a table.
1 2 3
<tk-pagination label="Table rows">
  <tk-pagination-prev value="1"></tk-pagination-prev>
  <tk-pagination-item value="1">1</tk-pagination-item>
  <tk-pagination-item value="2" current>2</tk-pagination-item>
  <tk-pagination-item value="3">3</tk-pagination-item>
  <tk-pagination-next value="3"></tk-pagination-next>
</tk-pagination>
pagination.addEventListener('tk-page-select', (e) => showPage(e.detail.value));

current marks the page on screen. It stays clickable; don't disable it.

Previous and next

Prev and next show a chevron and are named "Previous page" and "Next page". Set disabled on prev at the first page and on next at the last.

Previous 2 3 Next
<tk-pagination label="Search results">
  <tk-pagination-prev href="?page=2">Previous</tk-pagination-prev>
  <tk-pagination-item href="?page=2">2</tk-pagination-item>
  <tk-pagination-item href="?page=3" current>3</tk-pagination-item>
  <tk-pagination-next disabled>Next</tk-pagination-next>
</tk-pagination>

Text inside prev or next shows next to the chevron. The accessible name stays "Previous page" or "Next page", so keep the visible word inside it.

Which pages to show

The component never decides which numbers or ellipses appear. A common pattern shows the first page, the last, and the current page with one neighbor on each side, with an ellipsis for each gap:

function pageWindow(current, total, siblings = 1) {
  const range = (s, e) => Array.from({ length: e - s + 1 }, (_, i) => s + i);
  if (total <= siblings * 2 + 5) return range(1, total);
  const left = Math.max(current - siblings, 2);
  const right = Math.min(current + siblings, total - 1);
  return [
    1,
    ...(left > 2 ? ['…'] : []),
    ...range(left, right),
    ...(right < total - 1 ? ['…'] : []),
    total,
  ]; // pageWindow(4, 20) → [1, '…', 3, 4, 5, '…', 20]
}

Render each number as a tk-pagination-item, with current on the active one, and each '…' as a tk-pagination-ellipsis.

Sizes

There is one size. To make the row more compact, set --tk-pagination-cell-size on tk-pagination; keep it at 24px or more.

1 2
<tk-pagination label="Comments" style="--tk-pagination-cell-size: 32px">
  <tk-pagination-prev disabled></tk-pagination-prev>
  <tk-pagination-item value="1" current>1</tk-pagination-item>
  <tk-pagination-item value="2">2</tk-pagination-item>
  <tk-pagination-next value="2"></tk-pagination-next>
</tk-pagination>

A cell is square and grows for longer numbers. Numbers use tabular digits, so they line up. The row wraps when it runs out of room.