component :: Pagination

Two navigation patterns for content sites: .pagination is the numbered kind for blog indexes, .prevNext the pair of cards at the bottom of a post. Both are pure HTML and CSS.

FileDescriptionSource
component.pagination.cssNumbered pagination stylesGithub
component.prevNext.cssPrev/next stylesGithub
Pagination.astro, PrevNext.astroThe Astro componentsGithub
icons/chevron-down.svgArrow icon (rotated in CSS)Github
--pagination-*, --prevNext-* theme blocksTheme tokens (see table below)Github

HTML

The numbers are windowed around the current page, so long lists stay short.

<nav class="pagination" aria-label="Pagination">
<ul>
<li><a class="pagination_arrow pagination_arrow-prev" href="/blog/4" aria-label="Previous page"><svg>[…]</svg></a></li>
<li><a href="/blog" aria-label="Page 1">1</a></li>
<li><span class="pagination_ellipsis" aria-hidden="true">…</span></li>
<li><a href="/blog/4" aria-label="Page 4">4</a></li>
<li><a href="/blog/5" aria-current="page" aria-label="Page 5">5</a></li>
<li><a href="/blog/6" aria-label="Page 6">6</a></li>
<li><span class="pagination_ellipsis" aria-hidden="true">…</span></li>
<li><a href="/blog/12" aria-label="Page 12">12</a></li>
<li><a class="pagination_arrow pagination_arrow-next" href="/blog/6" aria-label="Next page"><svg>[…]</svg></a></li>
</ul>
</nav>

At the ends, the arrows stay in place but become disabled <span aria-disabled="true"> elements instead of links, so the layout never jumps. Every target is at least --pagination-size (36px) square.

<nav class="prevNext" aria-label="Previous and next">
<a class="prevNext_link prevNext_link-prev" href="/blog/layers">
<small>Previous</small>
<span>Designing with cascade layers</span>
</a>
<a class="prevNext_link prevNext_link-next" href="/blog/tokens">
<small>Next</small>
<span>Tokens all the way down</span>
</a>
</nav>

A lone next link keeps its right-hand column.

Custom properties

PropertyDescription
--pagination-sizeMinimum width/height of a target.
--pagination-border-radiusTarget border radius.
--pagination-colorNumber/arrow color.
--pagination-color-currentCurrent page text color.
--pagination-background-color-currentCurrent page background.
--pagination-background-color-hoverHover background.
--prevNext-border-colorCard border.
--prevNext-border-color-hoverCard border on hover.
--prevNext-label-color”Previous”/“Next” label color.

Astro component

Pagination

PropTypeDefaultDescription
currentPagenumberThe page being rendered. Required.
lastPagenumberTotal number of pages. Required.
baseUrlstringIndex URL; page 1 is baseUrl, page n is baseUrl/n.
pageUrl(page: number) => stringsee baseUrlOverride the URL scheme entirely.
windowSizenumber1Pages shown on each side of the current one.
ariaLabelstring"Pagination"The nav’s accessible name.

With Astro’s paginate(), pass page.currentPage, page.lastPage, and your index route as baseUrl.

PrevNext

PropTypeDefaultDescription
prev{ title, href }undefinedPrevious post link.
next{ title, href }undefinedNext post link.
prevLabelstring"Previous"Small label above the prev title.
nextLabelstring"Next"Small label above the next title.
ariaLabelstring"Previous and next"The nav’s accessible name.

Renders nothing when both links are missing.

Examples