Novus Technologies Novus Technologies design kit v0.9.0
Menu

Navigation

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

Showing 11-20 of 24
Page 2 of 3
List footer (every paged data list)
<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>
Showing 0 of 0
Page 1 of 1
Nothing to page: zero results
<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>
Numbered pages (long documents and search results)
<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.

@pattern list-footer
.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); }