Menu
Overview
General
ButtonBadgePillsAvatarBrand lockupLayout
ContainerGrid & RowSurface & text utilitiesApp shellPage headerData Display
CardTableChartsCalendarStatsBulletsLeadersLogo wallCollapse & DisclosureTimelineValue chainDescriptionsFeedback
AlertProgressModalSlide-overSkeletonEmpty stateForms
Field & InputDropdownLead form & CTA rowDate pickerFilter barNavigation
NavSide navigationTop navigationApp switcherUser menuStepperTabsBreadcrumbPaginationTemplates
Sign-in pageSigned-out pageSettings layoutTheming
Browser tabProduct themesNavigation
Pagination
List footer for data lists (range, previous and next, page label, rows per page), plus numbered pages for long documents.
.listfooter · .paginator · composes .btn · aria-current=page
<div class="listfooter">
<span class="listfooter__range">Showing 11-20 of 24</span>
<div class="listfooter__controls">
<div class="paginator">
<button type="button" aria-label="Previous page"><svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m15 6-6 6 6 6"/></svg></button>
<span class="paginator__label">Page 2 of 3</span>
<button type="button" aria-label="Next page"><svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m9 6 6 6-6 6"/></svg></button>
</div>
<span class="selectwrap"><select class="select" aria-label="Rows per page"><option>10 / page</option><option>20 / page</option><option>50 / page</option></select></span>
</div>
</div>
<div class="listfooter">
<span class="listfooter__range">Showing 0 of 0</span>
<div class="listfooter__controls">
<div class="paginator">
<button type="button" aria-label="Previous page" disabled><svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m15 6-6 6 6 6"/></svg></button>
<span class="paginator__label">Page 1 of 1</span>
<button type="button" aria-label="Next page" disabled><svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m9 6 6 6-6 6"/></svg></button>
</div>
<span class="selectwrap"><select class="select" aria-label="Rows per page"><option>10 / page</option><option>20 / page</option><option>50 / page</option></select></span>
</div>
</div>
<nav aria-label="Pagination" class="row" style="gap:var(--space-1)">
<button class="btn btn--ghost btn--sm" aria-label="Previous page"><svg class="icon icon--sm" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m15 6-6 6 6 6"/></svg></button>
<button class="btn btn--ghost btn--sm">1</button>
<button class="btn btn--secondary btn--sm" aria-current="page" style="border-color:var(--accent);color:var(--accent-text)">2</button>
<button class="btn btn--ghost btn--sm">3</button>
<span class="muted" style="padding:0 var(--space-1)">…</span>
<button class="btn btn--ghost btn--sm">12</button>
<button class="btn btn--ghost btn--sm" aria-label="Next page"><svg class="icon icon--sm" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m9 6 6 6-6 6"/></svg></button>
</nav>
Usage
- Every paged data list ends with the list footer: the range at the start; previous, the page label, next, and rows per page at the end.
- Rows per page offers 10, 20, and 50, defaulting to 10. Changing it returns to page 1.
- Previous is disabled on the first page and next on the last; both are 44px icon buttons with names.
- The range always states the total: "Showing 21-24 of 24" on a short last page, "Showing 0 of 0" when nothing matches.
- Numbered pages suit long documents and search results where jumping matters; the current page carries the accent border and
aria-current="page".
CSS
These rules ship in the console pattern layer, admin-kits/shared/novus-admin.css, which this site and every Admin Kit flavor load after tokens.css. Copy the whole layer, or only the sections below; every value is a token.
.listfooter { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--space-3); margin-top: var(--space-3); font-size: var(--text-sm); line-height: var(--lh-sm); }
.listfooter__range { color: var(--text-secondary); font-variant-numeric: tabular-nums; }
.listfooter__controls { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-3); }
.listfooter .selectwrap { display: inline-block; }
.paginator { display: flex; align-items: center; gap: var(--space-2); color: var(--text-secondary); font-variant-numeric: tabular-nums; }
.paginator button { display: inline-flex; align-items: center; justify-content: center; min-width: 2.75rem; min-height: 2.75rem; padding: 0; font: inherit; color: var(--accent-text); background: var(--surface); border: 1px solid var(--border-strong); border-radius: var(--radius-md); cursor: pointer; transition: background-color 0.15s ease, border-color 0.15s ease; }
.paginator button:hover:not(:disabled) { background: var(--accent-subtle); border-color: var(--accent); }
.paginator button:focus-visible { outline: none; box-shadow: var(--focus-ring); }
.paginator button:disabled { opacity: var(--opacity-disabled); cursor: default; }
.paginator__label { padding-inline: var(--space-1); color: var(--text); }