Pagination

Pagination is a fully CSS-driven navigation component for splitting content across multiple pages. It requires no JavaScript — all states and variants are controlled with declarative HTML classes.

Use Pagination for:

  • Data tables and search results
  • Blog post and article listings
  • File browsers and media galleries
  • Any content split across multiple pages

Getting Started

Apply .pagination to a <ul> element. Each page button is a <li class="page-item"> containing an <a class="page-link">.

<ul class="pagination">
  <li className="page-item">
    <a href="#" className="page-link  page-prev"></a>
  </li>
  <li className="page-item">
    <a href="#" className="page-link">1</a>
  </li>
  <li className="page-item is-active">
    <a href="#" className="page-link">2</a>
  </li>
  <li className="page-item">
    <a href="#" className="page-link">3</a></li>
  <li className="page-item is-disabled">
    <a href="#" className="page-link">…</a>
  </li>
  <li className="page-item">
    <a href="#" className="page-link">10</a>
  </li>
  <li className="page-item">
    <a href="#" className="page-link page-next"></a>
  </li>
</ul>

Structure

ElementClass / AttributePurpose
ContainerpaginationRoot class. Apply to <ul>. Accepts layout and size modifiers.
Item wrapperpage-itemEach <li> wrapper for a page button. Accepts state classes.
Linkpage-linkThe clickable <a> inside each item. Carries all visual styling.
Previous buttonpage-prevAdded to the prev <a>. Injects a left chevron icon via CSS ::before.
Next buttonpage-nextAdded to the next <a>. Injects a right chevron icon via CSS ::after.

Item States

State modifiers are applied to individual .page-item elements.

ModifierApplies toEffect
is-activepage-itemMarks the current page. Background fills with --accent, text becomes --accent-contrast, cursor becomes default.
is-disabledpage-itemMakes the item non-interactive. Applies pointer-events: none and muted text color via --muted.

is-active

Highlights the current page. The background fills with --accent and text color switches to --accent-contrast.

<ul class="pagination">
  <li class="page-item is-disabled">
    <a href="#" class="page-link page-prev" aria-disabled="true">Prev</a>
  </li>
  <li class="page-item is-active">
    <a href="#" class="page-link">1</a>
  </li>
  <li class="page-item">
    <a href="#" class="page-link">2</a>
  </li>
  <li class="page-item">
    <a href="#" class="page-link">3</a>
  </li>
  <li class="page-item">
    <a href="#" class="page-link page-next">Next</a>
  </li>
</ul>

is-disabled

Makes the item non-interactive via pointer-events: none and renders text in --muted. For full accessibility, also add aria-disabled="true" to the inner <a> element.

<ul class="pagination">
  <li class="page-item">
    <a href="#" class="page-link page-prev">Prev</a>
  </li>
  <li class="page-item">
    <a href="#" class="page-link">1</a>
  </li>
  <li class="page-item is-disabled">
    <a href="#" class="page-link" aria-disabled="true">…</a>
  </li>
  <li class="page-item">
    <a href="#" class="page-link">9</a>
  </li>
  <li class="page-item">
    <a href="#" class="page-link page-next">Next</a>
  </li>
</ul>

is-disabled blocks mouse and hover events at the CSS level. Always pair with aria-disabled="true" on the <a> element for keyboard and screen reader accessibility.


Layout Modes

ModifierEffect
default (separated)Each item is an individual rounded button with a 0.25rem gap. All corners of .page-link receive --radius-1.
is-groupedItems join into a single continuous bar with no gaps. Only the first and last items have outer rounded corners, via CSS logical properties for RTL compatibility.

Separated (Default)

Each page item is an individual button separated by a 0.25rem gap. All four corners of .page-link receive border-radius via --radius-1.

is-grouped

Items join into a single continuous bar with no gaps. The first item gets start-side rounded corners and the last gets end-side rounded corners — using CSS logical properties (border-start-start-radius, border-end-end-radius) for full RTL support.

<ul class="pagination is-grouped">
  <li class="page-item"><a href="#" class="page-link page-prev">Prev</a></li>
  <li class="page-item"><a href="#" class="page-link">1</a></li>
  <li class="page-item is-active"><a href="#" class="page-link">2</a></li>
  <li class="page-item"><a href="#" class="page-link">3</a></li>
  <li class="page-item"><a href="#" class="page-link page-next">Next</a></li>
</ul>

Prev & Next Chevron Icons

The previous and next chevron icons are rendered entirely via CSS ::before and ::after pseudo-elements using mask-image. No icon font, inline SVG, or extra markup is required — add .page-prev or .page-next to the <li>.

<ul class="pagination">
  <li class="page-item">
    <a href="#" class="page-link page-prev">Prev</a>
  </li>
  <li class="page-item">
    <a href="#" class="page-link page-next">Next</a>
  </li>
</ul>

The chevron color always matches currentColor, so it adapts automatically to hover, active, and disabled states without extra CSS.

RTL Support

In right-to-left layouts both chevrons are automatically mirrored via scaleX(-1) using the :dir(rtl) CSS pseudo-class. No extra classes or overrides are needed.

<ul class="pagination" dir="rtl">
  <li class="page-item"><a href="#" class="page-link page-prev">السابق</a></li>
  <li class="page-item is-active"><a href="#" class="page-link">١</a></li>
  <li class="page-item"><a href="#" class="page-link">٢</a></li>
  <li class="page-item"><a href="#" class="page-link page-next">التالي</a></li>
</ul>

Size Variants

Size modifiers are applied to the .pagination container and scale all items uniformly.

ClassItem HeightMin WidthFont Size
default2.5rem2.5rem1rem
is-small2rem2rem0.875rem
is-large3rem3rem1.25rem
<!-- Small -->
<ul class="pagination is-small">
  <li class="page-item"><a href="#" class="page-link page-prev">Prev</a></li>
  <li class="page-item is-active"><a href="#" class="page-link">1</a></li>
  <li class="page-item"><a href="#" class="page-link">2</a></li>
  <li class="page-item"><a href="#" class="page-link page-next">Next</a></li>
</ul>

<!-- Large -->
<ul class="pagination is-large">
  <li class="page-item"><a href="#" class="page-link page-prev">Prev</a></li>
  <li class="page-item is-active"><a href="#" class="page-link">1</a></li>
  <li class="page-item"><a href="#" class="page-link">2</a></li>
  <li class="page-item"><a href="#" class="page-link page-next">Next</a></li>
</ul>

Accessibility

  • Use <ul> as the container and wrap the whole component in <nav aria-label="Pagination"> for landmark navigation.
  • Add aria-current="page" to the active <a> element alongside is-active.
  • Add aria-disabled="true" to the <a> inside every .is-disabled item — CSS pointer-events: none alone does not prevent keyboard focus.
  • Focus rings are rendered via outline and box-shadow using --accent and do not affect layout.

Notes

  • Pagination requires no JavaScript — all states are controlled via HTML classes.
  • The link class is page-link, not nav-link — use .page-item .page-link in all markup.
  • Active state uses --accent and --accent-contrast, not --primary and --body-bg.
  • Disabled state text color comes from --muted, not --text-muted.
  • is-disabled on a .page-item is also the correct way to render a non-interactive ellipsis separator.
  • Chevron icons use currentColor via mask-image — they automatically adapt to all states.
  • RTL chevron mirroring is automatic via :dir(rtl) and requires no extra classes.
  • Size modifiers apply to the .pagination container, not individual .page-item elements.
  • is-grouped and size modifiers can be combined: pagination is-grouped is-medium is valid.

FrontAlign