You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Evaluate a pagination component (upstream pico discussion #368) #62
Upstream: picocss/pico discussion #368 (11 upvotes, 0 comments — asked, never answered), found during a sweep of picocss/pico's Discussions for items not yet covered by cirth's M5 audit.
Problem
No pagination pattern exists in cirth today (checked: no matches for "pagination" anywhere in src/). It's a common content-navigation need (docs sites, blogs, tables, search results) and reasonably cheap to design well: essentially a <nav> + list of page links/buttons, in the same spirit as the existing .group component (joined, adjacent controls) rather than a net-new mechanism.
Ask
Design a minimal, classless-first pagination pattern:
Likely <nav aria-label="Pagination"><ul>...<li><a aria-current="page">...</a> — reuse the existing [aria-current] handling already wired into nav/button styling rather than inventing new state markup.
Decide whether it needs its own component file or is a documented composition of existing primitives (nav + group-like joining) — lean toward the latter if it gets you 90% of the value with zero new CSS surface, consistent with how .breakout/.sr-only were scoped in M3.
Acceptance
A written decision on scope (new component vs. documented composition of existing primitives).
If new markup/CSS is needed: docs page, live demo, a11y-audited.
If it's a composition: a docs page (likely under Examples, gh#29) showing the recommended markup.
Pagination is a good fit for Cirth because its complete interaction can be implemented with native links and navigation semantics, without JavaScript or hidden state.
The main design decision is how Cirth should identify a pagination navigation region for styling.
The available options are:
document pagination as a composition of existing HTML and Cirth primitives;
infer pagination through structural selectors and semantic attributes;
introduce an explicit .pagination class.
Unlike tabs, all three options preserve native and accessible functionality. The choice is mainly about API design and consistency with Cirth’s philosophy.
Recommended markup
The semantic foundation should remain the same regardless of the styling option:
aria-disabled communicates a state but does not cancel navigation. Similarly, pointer-events: none only affects pointer interaction and does not provide an equivalent keyboard-disabled state.
Ellipses
An ellipsis representing omitted pages should not be interactive:
<liaria-hidden="true">…</li>
If it opens a page-selection control, it is no longer presentational and should instead be implemented as a correctly labelled button.
Option A: composition of existing primitives
Cirth could document pagination without adding a dedicated selector.
The pattern would rely on the existing styles for:
<nav>;
<ul> and <li>;
links;
[aria-current="page"];
focus indication;
target sizing.
Advantages:
no new class;
no new component API;
compatible with the classless build;
markup remains entirely semantic;
very small maintenance cost.
Trade-off:
Cirth cannot reliably apply pagination-specific alignment, spacing or responsive behaviour without also affecting other navigation lists.
This option is the most strictly semantic, but it may only provide an example rather than a recognisable pagination component.
Option B: infer pagination through semantic structure
Cirth could infer the component from rel="prev" or rel="next":
HTML can express that the element is navigation, and aria-current, rel="prev" and rel="next" express important relationships. However, HTML has no dedicated pagination element or pagination role. It cannot explicitly distinguish a pagination <nav> from site navigation, breadcrumbs, table-of-contents navigation or other link collections in a way that is both reliable and suitable as a CSS selector.
This means .pagination could reasonably qualify as one of the limited cases where a class expresses a distinction that HTML cannot express on its own:
<navclass="pagination" aria-label="Pagination">
nav.pagination>ul{/* Pagination layout */}nav.pagination [aria-current="page"] {/* Current page presentation */}
Advantages:
explicit author intent;
simple and stable selectors;
no dependency on localized text;
no structural heuristic;
consistent with the existing class-based escape hatches;
easy to document and customize;
removing the class or stylesheet leaves correct semantic HTML.
Trade-offs:
adds another term to Cirth’s class vocabulary;
is unavailable as a dedicated component in the classless build;
risks contributing to a component catalog if similar classes are added without a strict threshold;
some generic navigation styling may already be sufficient.
The relevant question is therefore not whether Cirth permits classes—it already does—but whether pagination is common and distinct enough to justify one of the framework’s intentionally limited escape hatches.
Why .pagination may be preferable to data-pagination
An explicit data attribute would also work:
<navdata-paginationaria-label="Pagination">
However, if Cirth decides that an explicit hook is necessary, .pagination is probably more consistent with the existing public API.
The framework already uses named classes for HTML distinctions that cannot be represented natively. Introducing a data attribute for a purely presentational component distinction would create a second convention without providing a clear advantage.
Therefore, the choice should probably be between:
no explicit hook; or
the conventional .pagination class.
Rejected option: using the accessible name
Cirth should not use:
nav[aria-label="Pagination"]
The accessible name is content, not a styling API.
Using the label as a selector would couple visual presentation to language and author wording.
A non-standard role such as role="pagination" should not be introduced either.
Recommended styling scope
Whether or not .pagination is adopted, Cirth can provide or document:
visual treatment for [aria-current="page"];
sufficient link padding;
visible keyboard focus;
wrapping on narrow viewports;
spacing between adjacent targets;
logical source and reading order;
forced-colours compatibility.
Pagination links should have an active area of at least 24 × 24 CSS pixels or satisfy the applicable spacing exception. Cirth’s documented 44px accessibility floor would exceed this minimum.
No functionality should depend on pagination-specific CSS.
Progressive degradation
All three approaches degrade safely.
With .pagination:
the default build provides the dedicated presentation;
the classless build presents an ordinary navigation list;
removing Cirth leaves valid and functional HTML;
browsers without advanced CSS still expose every link;
ARIA support does not affect navigation functionality;
no hidden panel or overlay can become permanently visible.
This matches the principle described on the About page: markup should remain correct, accessible and machine-readable if the stylesheet is removed.
!important policy
No !important declarations are necessary. Pagination can be implemented with ordinary selectors, source order and the existing cascade.
Recommended decision
Implement pagination as a semantic HTML pattern.
Before implementation, decide whether pagination-specific presentation is substantial enough to justify an explicit API:
if existing navigation styles are sufficient, document the pattern without a class;
if pagination needs its own layout, responsive rules and state presentation, adopt nav.pagination;
avoid localization-dependent selectors;
avoid non-standard ARIA roles;
prefer .pagination over a data-pagination attribute if an explicit hook is required;
keep the class absent from the classless build, where the semantic navigation remains fully functional.
My preference would be .pagination if the final design is visually or structurally distinct from an ordinary <nav>. It appears consistent with the stated policy that classes are reserved as escape hatches for distinctions HTML cannot express, while still preserving Cirth’s semantic-first baseline.
Activity
ricpastori commentedon Aug 15, 2026
Proposed direction
Pagination is a good fit for Cirth because its complete interaction can be implemented with native links and navigation semantics, without JavaScript or hidden state.
The main design decision is how Cirth should identify a pagination navigation region for styling.
The available options are:
.paginationclass.Unlike tabs, all three options preserve native and accessible functionality. The choice is mainly about API design and consistency with Cirth’s philosophy.
Recommended markup
The semantic foundation should remain the same regardless of the styling option:
If no dedicated class is adopted, the same markup remains valid without it:
The current page may also remain a link:
Both approaches can be valid:
aria-current="page"identifies the current item programmatically.Reference: WAI-ARIA aria-current
The navigation landmark should have an accessible name, especially when the document contains other navigation regions.
Reference: WAI-ARIA Navigation Landmark
The accessible name must be localized by the application.
Previous and next links
When a previous or next page is unavailable, the safest options are:
For example:
I would avoid an active link with only
aria-disabled="true":aria-disabledcommunicates a state but does not cancel navigation. Similarly,pointer-events: noneonly affects pointer interaction and does not provide an equivalent keyboard-disabled state.Ellipses
An ellipsis representing omitted pages should not be interactive:
If it opens a page-selection control, it is no longer presentational and should instead be implemented as a correctly labelled button.
Option A: composition of existing primitives
Cirth could document pagination without adding a dedicated selector.
The pattern would rely on the existing styles for:
<nav>;<ul>and<li>;[aria-current="page"];Advantages:
Trade-off:
This option is the most strictly semantic, but it may only provide an example rather than a recognisable pagination component.
Option B: infer pagination through semantic structure
Cirth could infer the component from
rel="prev"orrel="next":Advantages:
relvalues serve their actual purpose;:has()retain an ordinary navigation list.Trade-offs:
The functionality degrades safely, but the implicit detection may be less predictable than the rest of the framework.
Option C:
.paginationCirth already includes a deliberately small set of classes such as:
.secondary;.outline;.container;.container-fluid;.grid;.row.The project philosophy states that:
The default build includes a small number of classes for distinctions that HTML cannot express, while the classless build includes none.
Reference: [About Cirth — Why semantic HTML first](https://cirthcss.github.io/cirth/about/)
HTML can express that the element is navigation, and
aria-current,rel="prev"andrel="next"express important relationships. However, HTML has no dedicated pagination element or pagination role. It cannot explicitly distinguish a pagination<nav>from site navigation, breadcrumbs, table-of-contents navigation or other link collections in a way that is both reliable and suitable as a CSS selector.This means
.paginationcould reasonably qualify as one of the limited cases where a class expresses a distinction that HTML cannot express on its own:Advantages:
Trade-offs:
The relevant question is therefore not whether Cirth permits classes—it already does—but whether pagination is common and distinct enough to justify one of the framework’s intentionally limited escape hatches.
Why
.paginationmay be preferable todata-paginationAn explicit data attribute would also work:
However, if Cirth decides that an explicit hook is necessary,
.paginationis probably more consistent with the existing public API.The framework already uses named classes for HTML distinctions that cannot be represented natively. Introducing a data attribute for a purely presentational component distinction would create a second convention without providing a clear advantage.
Therefore, the choice should probably be between:
.paginationclass.Rejected option: using the accessible name
Cirth should not use:
The accessible name is content, not a styling API.
Its value may legitimately be:
Using the label as a selector would couple visual presentation to language and author wording.
A non-standard role such as
role="pagination"should not be introduced either.Recommended styling scope
Whether or not
.paginationis adopted, Cirth can provide or document:[aria-current="page"];Pagination links should have an active area of at least
24 × 24CSS pixels or satisfy the applicable spacing exception. Cirth’s documented44pxaccessibility floor would exceed this minimum.Reference: [Understanding WCAG 2.2 SC 2.5.8](https://www.w3.org/WAI/WCAG22/Understanding/target-size-minimum)
No functionality should depend on pagination-specific CSS.
Progressive degradation
All three approaches degrade safely.
With
.pagination:This matches the principle described on the About page: markup should remain correct, accessible and machine-readable if the stylesheet is removed.
!importantpolicyNo
!importantdeclarations are necessary. Pagination can be implemented with ordinary selectors, source order and the existing cascade.Recommended decision
Implement pagination as a semantic HTML pattern.
Before implementation, decide whether pagination-specific presentation is substantial enough to justify an explicit API:
nav.pagination;.paginationover adata-paginationattribute if an explicit hook is required;My preference would be
.paginationif the final design is visually or structurally distinct from an ordinary<nav>. It appears consistent with the stated policy that classes are reserved as escape hatches for distinctions HTML cannot express, while still preserving Cirth’s semantic-first baseline.