Navigation

v0.0.4
Navigation

Pager

The page before and the page after, at the foot of an article.

On this page

A pager is the page before and the page after, at the foot of an article: two links side by side, each a flat face with a quiet word over the title of the page it leads to. The links say which is which with rel="prev" and rel="next", and the stylesheet reads that, so there is no class for a direction.

Pager

<nav class="pager max-w(560) mx-auto" aria-label="Guide pages">  <a class="pager-link" rel="prev" href="#installation">    <span class="pager-label">Previous</span>    <span class="pager-title">Installation</span>  </a>  <a class="pager-link" rel="next" href="#theming">    <span class="pager-label">Next</span>    <span class="pager-title">Theming</span>  </a></nav>

#One attribute decides the side

rel is the HTML attribute that says how a link relates to the page it is on, and prev and next are two of its values. A pager's link carries one of them, which is correct markup for a sequence in any case; the stylesheet reads it to do three things:

  • The next page stands at the end of the row, with its words set to the end.
  • Its arrow follows the word and points forward; the arrow of the page before leads the word and points back. Both turn round in a right-to-left page.
  • A pager with only a next page keeps it at the end, where a reader's eye and thumb expect it.

Leave out the link that does not exist. The first page of a guide has only a next, and the last only a previous.

The first page

<nav class="pager max-w(560) mx-auto" aria-label="Guide pages">  <a class="pager-link" rel="next" href="#installation">    <span class="pager-label">Next</span>    <span class="pager-title">Installation</span>  </a></nav>

#Material and motion

A link is a flat face on one contour, with a large control's corner. Under the pointer it rises a step and its arrow moves 2px the way it points; pressed, it sinks into a well. With reduced motion the arrow stays where it is.

The pager is a size container. Under 26rem of its own width the two links stack, each as wide as the pager, the previous page first.

#Pager or pagination

A pager moves between pages that are read in an order, and names them. Pagination moves between the numbered pages of one long list. Where a page is in the site is a breadcrumb.

#Accessibility

  • Put the links in a <nav> with an aria-label, so the landmark says what it is among the other navigation of the page.
  • A link's name is its label and its title together: "Next, Theming". Keep the label; a title alone does not say which way it goes.
  • The arrows are drawn by the stylesheet and are not announced.

#Classes

ClassDescription
pagerThe two links side by side, on a nav with an accessible name; in a container under 26rem they stack
pager-linkOne link, with rel="prev" or rel="next": a flat face that rises a step under the pointer. The next page stands at the end with its words set to the end
pager-labelThe quiet word over the title, Previous or Next, with an arrow that points the way the link goes
pager-titleThe title of the page the link leads to

#Source

@master/ui/components/pager.css
/* * Pager: the page before and the page after, at the foot of an article. * Two links side by side, each a flat face with a quiet word over the title of the page it leads to. The * links say which is which with rel="prev" and rel="next", and the stylesheet reads that: the next page * stands at the end with its words set to the end, and an arrow points the way each one goes. A pager with * only a next page keeps it at the end. * Under the pointer a link rises a step and its arrow moves 2px the way it points. In a narrow container the * two stack. * Geometry: a large control's corner, 14px by 16px of padding, 12px between the two. */@layer components {  .pager {    container-type: inline-size;    display: grid;    grid-template-columns: repeat(2, minmax(0, 1fr));    gap: .75rem;    min-width: 0;    margin: 0;    padding: 0;    list-style: none;    @container (width < 26rem) {      .pager-link, .pager-link[rel~="next"] {        grid-column: 1 / -1;      }    }  }  .pager-link {    --pager-travel: 0px;    display: grid;    gap: .125rem;    min-width: 0;    padding: .875rem 1rem;    border-radius: calc(var(--radius-control-lg) * var(--corner-scale));    corner-shape: var(--corner-shape);    background: var(--color-surface-raised);    color: var(--color-text-body);    box-shadow: var(--shadow-flat);    text-decoration: none;    touch-action: manipulation;    -webkit-tap-highlight-color: transparent;    transition: box-shadow var(--duration-quick) var(--easing-glide);    /* The page after: at the end, with its words set to the end. */    &[rel~="next"] {      grid-column: 2;      justify-items: end;      text-align: end;    }    @media (hover: hover) {      &:hover {        --pager-travel: 2px;        box-shadow: var(--shadow-raised);      }    }    &:active {      background: var(--color-surface-inset);      box-shadow: var(--shadow-pressed);      transition-duration: var(--duration-press);    }    &:focus-visible {      @apply --focus-ring;    }    @media (prefers-reduced-motion: reduce) {      --pager-travel: 0px;      &:hover {        --pager-travel: 0px;      }    }    @media (forced-colors: active) {      outline: 1px solid LinkText;      outline-offset: -1px;    }  }  /* The quiet word: Previous, Next. Its arrow points the way the link goes. */  .pager-label {    display: inline-flex;    align-items: center;    gap: .25rem;    color: var(--color-text-muted);    font-size: .78125rem;    line-height: 1.25rem;    &::before, &::after {      flex: none;      width: .875rem;      height: .875rem;      background: currentColor;      mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3.5 8h9m0 0L9 4.5M12.5 8 9 11.5'/%3E%3C/svg%3E") center / contain no-repeat;      transition: translate var(--duration-quick) var(--easing-glide);    }  }  /* The arrow of the page before leads the word and points back. */  .pager-link:not([rel~="next"]) .pager-label::before {    content: '';    scale: -1 1;    translate: calc(-1 * var(--pager-travel)) 0;  }  .pager-link[rel~="next"] .pager-label::after {    content: '';    translate: var(--pager-travel) 0;  }  .pager-link:not([rel~="next"]) .pager-label:dir(rtl)::before {    scale: none;    translate: var(--pager-travel) 0;  }  .pager-link[rel~="next"] .pager-label:dir(rtl)::after {    scale: -1 1;    translate: calc(-1 * var(--pager-travel)) 0;  }  /* The title of the page it leads to. */  .pager-title {    min-width: 0;    color: var(--color-text-strong);    font-weight: var(--font-weight-control);    font-size: .9375rem;    line-height: 1.35;    text-wrap: balance;    overflow-wrap: anywhere;  }  @media (forced-colors: active) {    .pager-label::before, .pager-label::after {      background: LinkText;    }  }}