Vanilla Breeze

data-paged

Pagination upscale for any list-shaped container — native ul/ol/table or VB collections like card-list, data-table, layout-grid. Numbered, prev/next, load-more, and infinite styles. Optional URL state.

Overview

The data-paged attribute upscales any list-shaped container with pagination — native lists (<ul>, <ol>), tables (<table>, paginates the <tbody> rows), or VB collections (<card-list>, <data-table>, <layout-grid>). One attribute on the container, no per-element wiring; the script slices direct children, hides those outside the active page, and injects a <nav aria-label="Pagination"> sibling with the controls.

Styles

Four data-paged-style values cover the common pagination shapes:

numbered (default)
Prev / 1 2 3 … / Next. Best for indexed content like blog posts or product listings.
prev-next
Previous / "Page N of M" / Next. Best for linear sequences (tutorials, multi-step forms).
load-more
Single button reveals the next page worth of items in place. Best for activity-style feeds.
infinite
IntersectionObserver sentinel auto-loads more when scrolled into view. Best for endless feeds where users scroll without thinking about pages.

Attributes

AttributeDefaultNotes
data-pagedOpt-in (boolean).
data-paged-size10Items per page. 0 disables paging (single page covering all items).
data-paged-page1Initial page (1-based, user-facing).
data-paged-stylenumberednumbered · prev-next · load-more · infinite
data-paged-window2For numbered: page numbers shown around current before ellipsis kicks in.
data-paged-controlsafterbefore · after · both · none
data-paged-urlOpt-in URL search-param name (e.g. page). When set, page state syncs to the address bar via the History API and back/forward navigates.

Events

The container emits paged:change after each render. Use it for analytics, scroll-restoration, or driving a sibling component.

Composition recipe — content feed

The pattern that would have been <content-feed> is a recipe over existing primitives plus this attribute. No wrapper component required.

site-search handles filtering and highlighting; <card-list> handles template-driven rendering; data-paged handles paging and URL state. Each piece is independently testable and re-composable.

Accessibility

  • The injected nav uses <nav aria-label="Pagination"> with native <button>s — keyboard-navigable by default.
  • The active page button gets aria-current="page".
  • Disabled prev/next buttons get the native disabled attribute (focusable but not actionable per WAI-ARIA pagination guidance — use aria-disabled if you need them focusable).
  • Ellipsis markers () get aria-hidden="true" so screen readers don't announce them.
  • prev-next style includes a live status ("Page N of M") with aria-live="polite".
  • Honours prefers-reduced-motion: no transitions on page change.

What gets paginated

The script paginates direct children of the host, with one exception: when the host is <table>, it paginates the <tbody> rows instead (so the <thead> and <tfoot> stay visible).

The injected <nav> nodes are placed as siblings of the host, not children — so they don't affect the host's grid / flex layout and don't trip its mutation observer.