Blocks · Navigation
Numbered pagination
Previous and next with icons, page numbers with a gap, the current page marked and the ends disabled, with a line about what is shown.
38% of the 2,073 sites in The UI Index have a navigation (790 sites).
Showing 41 to 50 of 118 posts
Showing 1 to 10 of 118 posts
Showing 111 to 118 of 118 posts
Showing 41 to 50 of 118 posts
Showing 1 to 10 of 118 posts
Showing 111 to 118 of 118 posts
Both previews render the same markup; the HTML tab below is that markup without a framework.
Install
- React
- npx shadcn@
latest add https:// www.themes.dev/ ui/ r/ numbered-pagination.json - Astro
- npx shadcn@
latest add https:// www.themes.dev/ ui/ r/ astro/ numbered-pagination.json
Or copy the files below into your project. They need clsx, tailwind-merge and the components they import, and the themes.dev UI theme. The HTML needs only the compiled CSS.
/** Numbered pagination as a section: previous and next with icons, the page numbers with a gap (…) where pages are
* skipped, the current page marked (aria-current) and the ends disabled. The links are the pagination item; this
* adds the row with a short line about what is on the page. Narrow rows swap the numbers for 'Page 5 of 12'. */
export const numberedPagination = {
root: 'mx-auto flex w-full max-w-6xl flex-col gap-3 px-6 py-6 @container',
summary: 'm-0 text-sm text-muted-foreground tabular-nums',
nav: 'w-full',
};import { Pagination } from '@/components/ui/pagination';
import { cn } from '@/lib/utils';
import { numberedPagination as c } from './numbered-pagination.classes';
export interface NumberedPaginationProps {
current: number;
total: number;
/** The address of a page, e.g. (p) => `/blog/page/${p}/`. */
href: (page: number) => string;
/** The accessible name of the nav; give each pager on a page its own. */
label?: string;
/** A line before the pages, e.g. "Showing 41 to 50 of 118 posts". */
summary?: string;
className?: string;
}
export function NumberedPagination({ current, total, href, label = 'Pages', summary, className }: NumberedPaginationProps) {
return (
<div className={cn(c.root, className)}>
{summary && <p className={c.summary}>{summary}</p>}
<Pagination current={current} total={total} href={href} label={label} className={c.nav} />
</div>
);
}---
import Pagination from '@/components/ui/pagination.astro';
import { cn } from '@/lib/utils';
import { numberedPagination as c } from './numbered-pagination.classes';
interface Props {
current: number;
total: number;
/** The address of a page, e.g. (p) => `/blog/page/${p}/`. */
href: (page: number) => string;
/** The accessible name of the nav; give each pager on a page its own. */
label?: string;
/** A line before the pages, e.g. "Showing 41 to 50 of 118 posts". */
summary?: string;
class?: string;
}
const { current, total, href, label = 'Pages', summary, class: className } = Astro.props;
---
<div class={cn(c.root, className)}>
{summary && <p class={c.summary}>{summary}</p>}
<Pagination current={current} total={total} href={href} label={label} class={c.nav} />
</div>/** Numbered pagination as a section: previous and next with icons, the page numbers with a gap (…) where pages are
* skipped, the current page marked (aria-current) and the ends disabled. The links are the pagination item; this
* adds the row with a short line about what is on the page. Narrow rows swap the numbers for 'Page 5 of 12'. */
export const numberedPagination = {
root: 'mx-auto flex w-full max-w-6xl flex-col gap-3 px-6 py-6 @container',
summary: 'm-0 text-sm text-muted-foreground tabular-nums',
nav: 'w-full',
};<div class="grid w-full gap-2">
<div class="mx-auto flex w-full max-w-6xl flex-col gap-3 px-6 py-6 @container">
<p class="m-0 text-sm text-muted-foreground tabular-nums">Showing 41 to 50 of 118 posts</p>
<nav aria-label="Posts, pages" class="@container w-full">
<ul class="m-0 flex list-none flex-wrap items-center gap-1 p-0">
<li>
<a href="#page-4" rel="prev" class="inline-flex h-9 min-w-9 cursor-pointer items-center justify-center gap-1 rounded-md border border-transparent px-2.5 text-sm font-medium tabular-nums transition-[color,background-color,transform] select-none hover:bg-accent active:scale-[0.97] active:bg-pressed aria-[current=page]:border aria-[current=page]:border-input aria-[current=page]:bg-background aria-[current=page]:shadow-[0_1px_2px_rgb(0_0_0/0.06)] aria-disabled:pointer-events-none aria-disabled:opacity-50 [&_svg]:size-4">
<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M10 3.5L5.5 8l4.5 4.5"></path></svg>
<span class="@max-md:sr-only">Previous</span>
</a>
</li>
<li class="@max-lg:hidden">
<a href="#page-1" aria-label="Page 1" class="inline-flex h-9 min-w-9 cursor-pointer items-center justify-center gap-1 rounded-md border border-transparent px-2.5 text-sm font-medium tabular-nums transition-[color,background-color,transform] select-none hover:bg-accent active:scale-[0.97] active:bg-pressed aria-[current=page]:border aria-[current=page]:border-input aria-[current=page]:bg-background aria-[current=page]:shadow-[0_1px_2px_rgb(0_0_0/0.06)] aria-disabled:pointer-events-none aria-disabled:opacity-50 [&_svg]:size-4">
1
</a>
</li>
<li class="@max-lg:hidden"><span aria-hidden="true" class="inline-flex h-9 min-w-6 items-center justify-center text-sm text-muted-foreground">…</span></li>
<li class="@max-lg:hidden">
<a href="#page-4" aria-label="Page 4" class="inline-flex h-9 min-w-9 cursor-pointer items-center justify-center gap-1 rounded-md border border-transparent px-2.5 text-sm font-medium tabular-nums transition-[color,background-color,transform] select-none hover:bg-accent active:scale-[0.97] active:bg-pressed aria-[current=page]:border aria-[current=page]:border-input aria-[current=page]:bg-background aria-[current=page]:shadow-[0_1px_2px_rgb(0_0_0/0.06)] aria-disabled:pointer-events-none aria-disabled:opacity-50 [&_svg]:size-4">
4
</a>
</li>
<li class="@max-lg:hidden">
<a href="#page-5" aria-current="page" aria-label="Page 5" class="inline-flex h-9 min-w-9 cursor-pointer items-center justify-center gap-1 rounded-md border border-transparent px-2.5 text-sm font-medium tabular-nums transition-[color,background-color,transform] select-none hover:bg-accent active:scale-[0.97] active:bg-pressed aria-[current=page]:border aria-[current=page]:border-input aria-[current=page]:bg-background aria-[current=page]:shadow-[0_1px_2px_rgb(0_0_0/0.06)] aria-disabled:pointer-events-none aria-disabled:opacity-50 [&_svg]:size-4">
5
</a>
</li>
<li class="@max-lg:hidden">
<a href="#page-6" aria-label="Page 6" class="inline-flex h-9 min-w-9 cursor-pointer items-center justify-center gap-1 rounded-md border border-transparent px-2.5 text-sm font-medium tabular-nums transition-[color,background-color,transform] select-none hover:bg-accent active:scale-[0.97] active:bg-pressed aria-[current=page]:border aria-[current=page]:border-input aria-[current=page]:bg-background aria-[current=page]:shadow-[0_1px_2px_rgb(0_0_0/0.06)] aria-disabled:pointer-events-none aria-disabled:opacity-50 [&_svg]:size-4">
6
</a>
</li>
<li class="@max-lg:hidden"><span aria-hidden="true" class="inline-flex h-9 min-w-6 items-center justify-center text-sm text-muted-foreground">…</span></li>
<li class="@max-lg:hidden">
<a href="#page-12" aria-label="Page 12" class="inline-flex h-9 min-w-9 cursor-pointer items-center justify-center gap-1 rounded-md border border-transparent px-2.5 text-sm font-medium tabular-nums transition-[color,background-color,transform] select-none hover:bg-accent active:scale-[0.97] active:bg-pressed aria-[current=page]:border aria-[current=page]:border-input aria-[current=page]:bg-background aria-[current=page]:shadow-[0_1px_2px_rgb(0_0_0/0.06)] aria-disabled:pointer-events-none aria-disabled:opacity-50 [&_svg]:size-4">
12
</a>
</li>
<li class="inline-flex h-9 items-center px-2 text-sm text-muted-foreground tabular-nums @lg:hidden">Page 5 of 12</li>
<li>
<a href="#page-6" rel="next" class="inline-flex h-9 min-w-9 cursor-pointer items-center justify-center gap-1 rounded-md border border-transparent px-2.5 text-sm font-medium tabular-nums transition-[color,background-color,transform] select-none hover:bg-accent active:scale-[0.97] active:bg-pressed aria-[current=page]:border aria-[current=page]:border-input aria-[current=page]:bg-background aria-[current=page]:shadow-[0_1px_2px_rgb(0_0_0/0.06)] aria-disabled:pointer-events-none aria-disabled:opacity-50 [&_svg]:size-4">
<span class="@max-md:sr-only">Next</span>
<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M6 3.5l4.5 4.5L6 12.5"></path></svg>
</a>
</li>
</ul>
</nav>
</div>
<div class="mx-auto flex w-full max-w-6xl flex-col gap-3 px-6 py-6 @container">
<p class="m-0 text-sm text-muted-foreground tabular-nums">Showing 1 to 10 of 118 posts</p>
<nav aria-label="Posts, first page" class="@container w-full">
<ul class="m-0 flex list-none flex-wrap items-center gap-1 p-0">
<li>
<a aria-disabled="true" role="link" rel="prev" class="inline-flex h-9 min-w-9 cursor-pointer items-center justify-center gap-1 rounded-md border border-transparent px-2.5 text-sm font-medium tabular-nums transition-[color,background-color,transform] select-none hover:bg-accent active:scale-[0.97] active:bg-pressed aria-[current=page]:border aria-[current=page]:border-input aria-[current=page]:bg-background aria-[current=page]:shadow-[0_1px_2px_rgb(0_0_0/0.06)] aria-disabled:pointer-events-none aria-disabled:opacity-50 [&_svg]:size-4">
<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M10 3.5L5.5 8l4.5 4.5"></path></svg>
<span class="@max-md:sr-only">Previous</span>
</a>
</li>
<li class="@max-lg:hidden">
<a href="#page-1" aria-current="page" aria-label="Page 1" class="inline-flex h-9 min-w-9 cursor-pointer items-center justify-center gap-1 rounded-md border border-transparent px-2.5 text-sm font-medium tabular-nums transition-[color,background-color,transform] select-none hover:bg-accent active:scale-[0.97] active:bg-pressed aria-[current=page]:border aria-[current=page]:border-input aria-[current=page]:bg-background aria-[current=page]:shadow-[0_1px_2px_rgb(0_0_0/0.06)] aria-disabled:pointer-events-none aria-disabled:opacity-50 [&_svg]:size-4">
1
</a>
</li>
<li class="@max-lg:hidden">
<a href="#page-2" aria-label="Page 2" class="inline-flex h-9 min-w-9 cursor-pointer items-center justify-center gap-1 rounded-md border border-transparent px-2.5 text-sm font-medium tabular-nums transition-[color,background-color,transform] select-none hover:bg-accent active:scale-[0.97] active:bg-pressed aria-[current=page]:border aria-[current=page]:border-input aria-[current=page]:bg-background aria-[current=page]:shadow-[0_1px_2px_rgb(0_0_0/0.06)] aria-disabled:pointer-events-none aria-disabled:opacity-50 [&_svg]:size-4">
2
</a>
</li>
<li class="@max-lg:hidden"><span aria-hidden="true" class="inline-flex h-9 min-w-6 items-center justify-center text-sm text-muted-foreground">…</span></li>
<li class="@max-lg:hidden">
<a href="#page-12" aria-label="Page 12" class="inline-flex h-9 min-w-9 cursor-pointer items-center justify-center gap-1 rounded-md border border-transparent px-2.5 text-sm font-medium tabular-nums transition-[color,background-color,transform] select-none hover:bg-accent active:scale-[0.97] active:bg-pressed aria-[current=page]:border aria-[current=page]:border-input aria-[current=page]:bg-background aria-[current=page]:shadow-[0_1px_2px_rgb(0_0_0/0.06)] aria-disabled:pointer-events-none aria-disabled:opacity-50 [&_svg]:size-4">
12
</a>
</li>
<li class="inline-flex h-9 items-center px-2 text-sm text-muted-foreground tabular-nums @lg:hidden">Page 1 of 12</li>
<li>
<a href="#page-2" rel="next" class="inline-flex h-9 min-w-9 cursor-pointer items-center justify-center gap-1 rounded-md border border-transparent px-2.5 text-sm font-medium tabular-nums transition-[color,background-color,transform] select-none hover:bg-accent active:scale-[0.97] active:bg-pressed aria-[current=page]:border aria-[current=page]:border-input aria-[current=page]:bg-background aria-[current=page]:shadow-[0_1px_2px_rgb(0_0_0/0.06)] aria-disabled:pointer-events-none aria-disabled:opacity-50 [&_svg]:size-4">
<span class="@max-md:sr-only">Next</span>
<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M6 3.5l4.5 4.5L6 12.5"></path></svg>
</a>
</li>
</ul>
</nav>
</div>
<div class="mx-auto flex w-full max-w-6xl flex-col gap-3 px-6 py-6 @container">
<p class="m-0 text-sm text-muted-foreground tabular-nums">Showing 111 to 118 of 118 posts</p>
<nav aria-label="Posts, last page" class="@container w-full">
<ul class="m-0 flex list-none flex-wrap items-center gap-1 p-0">
<li>
<a href="#page-11" rel="prev" class="inline-flex h-9 min-w-9 cursor-pointer items-center justify-center gap-1 rounded-md border border-transparent px-2.5 text-sm font-medium tabular-nums transition-[color,background-color,transform] select-none hover:bg-accent active:scale-[0.97] active:bg-pressed aria-[current=page]:border aria-[current=page]:border-input aria-[current=page]:bg-background aria-[current=page]:shadow-[0_1px_2px_rgb(0_0_0/0.06)] aria-disabled:pointer-events-none aria-disabled:opacity-50 [&_svg]:size-4">
<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M10 3.5L5.5 8l4.5 4.5"></path></svg>
<span class="@max-md:sr-only">Previous</span>
</a>
</li>
<li class="@max-lg:hidden">
<a href="#page-1" aria-label="Page 1" class="inline-flex h-9 min-w-9 cursor-pointer items-center justify-center gap-1 rounded-md border border-transparent px-2.5 text-sm font-medium tabular-nums transition-[color,background-color,transform] select-none hover:bg-accent active:scale-[0.97] active:bg-pressed aria-[current=page]:border aria-[current=page]:border-input aria-[current=page]:bg-background aria-[current=page]:shadow-[0_1px_2px_rgb(0_0_0/0.06)] aria-disabled:pointer-events-none aria-disabled:opacity-50 [&_svg]:size-4">
1
</a>
</li>
<li class="@max-lg:hidden"><span aria-hidden="true" class="inline-flex h-9 min-w-6 items-center justify-center text-sm text-muted-foreground">…</span></li>
<li class="@max-lg:hidden">
<a href="#page-11" aria-label="Page 11" class="inline-flex h-9 min-w-9 cursor-pointer items-center justify-center gap-1 rounded-md border border-transparent px-2.5 text-sm font-medium tabular-nums transition-[color,background-color,transform] select-none hover:bg-accent active:scale-[0.97] active:bg-pressed aria-[current=page]:border aria-[current=page]:border-input aria-[current=page]:bg-background aria-[current=page]:shadow-[0_1px_2px_rgb(0_0_0/0.06)] aria-disabled:pointer-events-none aria-disabled:opacity-50 [&_svg]:size-4">
11
</a>
</li>
<li class="@max-lg:hidden">
<a href="#page-12" aria-current="page" aria-label="Page 12" class="inline-flex h-9 min-w-9 cursor-pointer items-center justify-center gap-1 rounded-md border border-transparent px-2.5 text-sm font-medium tabular-nums transition-[color,background-color,transform] select-none hover:bg-accent active:scale-[0.97] active:bg-pressed aria-[current=page]:border aria-[current=page]:border-input aria-[current=page]:bg-background aria-[current=page]:shadow-[0_1px_2px_rgb(0_0_0/0.06)] aria-disabled:pointer-events-none aria-disabled:opacity-50 [&_svg]:size-4">
12
</a>
</li>
<li class="inline-flex h-9 items-center px-2 text-sm text-muted-foreground tabular-nums @lg:hidden">Page 12 of 12</li>
<li>
<a aria-disabled="true" role="link" rel="next" class="inline-flex h-9 min-w-9 cursor-pointer items-center justify-center gap-1 rounded-md border border-transparent px-2.5 text-sm font-medium tabular-nums transition-[color,background-color,transform] select-none hover:bg-accent active:scale-[0.97] active:bg-pressed aria-[current=page]:border aria-[current=page]:border-input aria-[current=page]:bg-background aria-[current=page]:shadow-[0_1px_2px_rgb(0_0_0/0.06)] aria-disabled:pointer-events-none aria-disabled:opacity-50 [&_svg]:size-4">
<span class="@max-md:sr-only">Next</span>
<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M6 3.5l4.5 4.5L6 12.5"></path></svg>
</a>
</li>
</ul>
</nav>
</div>
</div>