Fylgja Pagination

Pagination is a row of numbered page links with previous and next controls, for moving through content split across pages. It is a labeled <nav> with the page numbers in a list and the previous/next controls beside it, all styled as buttons, with the current page marked.

Preview

<nav class="pagination flex gap-sm align" aria-label="Pagination">
	<a href="#" class="btn" aria-label="Previous page">
		<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m15 18-6-6 6-6"/></svg>
	</a>
	<ol class="flex flex-wrap gap-sm align">
		<li value="1"><a href="#" class="btn">1</a></li>
		<li value="2"><a href="#" class="btn" aria-current="page">2</a></li>
		<li value="3"><a href="#" class="btn">3</a></li>
		<li aria-hidden="true" class="hidden md:block">…</li>
		<li value="10" class="hidden md:block"><a href="#" class="btn">10</a></li>
	</ol>
	<a href="#" class="btn" aria-label="Next page">
		<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m9 18 6-6-6-6"/></svg>
	</a>
</nav>

<style>
	.pagination {
		--btn-active-stroke: var(--brand);
		--btn-active-bg: var(--brand);
		--btn-active-color: var(--on-brand);

		a {
			min-inline-size: 2.5em;
			min-block-size: 2.5em;
			border-width: 1px;
			border-radius: 2em;
			padding: 0.375em;
			font-size: 0.875em;
			line-height: 1.1;
			font-variant-numeric: tabular-nums;
		}
	}
</style>

Usage

  • Wrap everything in a labeled <nav class="pagination flex gap-sm align" aria-label="Pagination">, which also lays the row out.
  • Place the previous and next controls as icon <a class="btn"> (each with an aria-label) directly in the nav, so they sit outside the page list.
  • List the numbered pages in an <ol> of <li>, each an <a class="btn">, and mark the current page aria-current="page". Set each <li value="…"> to its page number so the sequence stays correct where it skips.
  • Collapse long ranges with an ellipsis in a <li aria-hidden="true"> (hide the whole item, not just its text, so it is not a stray empty list item), keeping the first, last, current, and adjacent pages.
  • The small .pagination style gives every link an equal, rounded target and colors the current page with the brand via the --btn-active-* variables.

Accessibility

  • The aria-label names the navigation landmark, and aria-current="page" marks the reader’s location.
  • Give the previous/next icon controls an aria-label (“Previous page” / “Next page”), and disable or omit them at the ends.

FAQ

Why doesn't Fylgja ship a Pagination component?

Pagination varies too much to bake into one component. It might have an ellipsis or not, show only prev/next, only numbers, or both, or be a checkout-style step pager. Fylgja gives the building blocks (buttons, utilities, and the aria-current style) and leaves the shape and styling to you, so you build exactly the pagination your case needs.

Why do the list items have a value attribute?

An ordered list numbers its items 1, 2, 3, and so on, and that ordinal is exposed to assistive tech. Pagination often skips, like 1, 2, 3, …, 10, so setting <li value="10"> makes the item's number match the real page instead of its position in the list. You do not need value when every page is shown in order with no gaps, since the numbers already line up.

How is the current page marked?

Give the current page's link aria-current="page". Fylgja's button active style targets [aria-current=page], so it highlights with no extra class.

How do I show skipped pages?

Use an ellipsis between page ranges, in a <li aria-hidden="true"> so the whole item is ignored by assistive tech. Keep the first, last, current, and adjacent pages as links.