web3icons

Infinite scroll vs pagination for galleries

Infinite scroll, pagination or a show more button for icon galleries, compared on findability, footer access, keyboard users and scroll restoration.

5 min read

A gallery of 2,000 crypto logos can't render everything at once, so you have to decide how people get past the first screen. The three common patterns are numbered pages, infinite scroll and a "Show more" button, and each fails in its own way. In an icon gallery, where many visitors search rather than browse, those failures play out differently than on a news feed or a store.

The three patterns

Pagination splits results into numbered pages, say 96 icons on page 1 and the next 96 on page 2. Each page usually gets its own URL, such as ?page=3.

Infinite scroll loads the next batch automatically when the user nears the bottom.

Show more appends the next batch when the user presses a button.

A common hybrid loads automatically but keeps a visible button as a fallback, or loads a few batches automatically and then switches to the button.

How they compare

Concern Pagination Infinite scroll Show more
Remembering a position ("it was on page 4") Easy Hard Hard
Linking to a position Yes No Only if the count is in the URL
Reaching the footer Always Hard; it keeps moving away Yes; the button stops the page
Effort to browse a lot A click per page None A click per batch
Back button after opening an icon Returns to the page Often loses the position Often loses the position
Keyboard and screen reader users Predictable Confusing without care Predictable with focus handling
DOM growth Bounded Unbounded Grows on request

Findability

Pagination gives every icon an address. Someone can say the logo they wanted was on the third page of networks, and it stays there as long as the order doesn't change. In an icon gallery, though, people rarely remember positions; they search. If search is good, position matters less, and continuous scrolling wins on browsing comfort. The guide on client-side search covers making search good enough to carry that weight.

What matters more is that the order is meaningful. A gallery sorted by popularity puts the logos most people want in the first batch, so many visitors never need the second one.

Infinite scroll makes the footer hard to reach: each time you get close, more content loads and pushes it away. If the footer holds links people need, such as licensing, about or contact information, that's a real problem.

Fixes, roughly in order of preference:

  • use a "Show more" button, which leaves the page at a natural end until someone asks for more;
  • load a limited number of batches automatically, then switch to the button;
  • move the essential links somewhere reachable, such as the header.

Keyboard and screen reader users

Automatic loading is designed around a scrolling pointer. Keyboard and screen reader users run into different problems.

Focus. When a "Show more" button adds items, the button moves below them and focus stays on it, so a keyboard user has to tab backwards to reach the new icons. Moving focus to the first new item after loading avoids that. When loading happens automatically during scrolling, leave focus where it is.

Announcements. Content that appears silently is easy to miss. Announce the change in a status region, as described by WCAG success criterion 4.1.3 Status Messages (AA):

<p role="status" className="visually-hidden">
  {`Showing ${shown} of ${total} icons`}
</p>

Reading order. A screen reader user who reads to the end of the grid may find new items appearing at that moment, or not at all if loading depends on scroll position. The ARIA Authoring Practices Guide describes a feed pattern for streams of articles that load as you read; for an icon grid, a real button that loads more on request is simpler and more predictable. If the grid supports arrow keys, see keyboard navigation in icon grids for how loading interacts with roving focus.

Restoring scroll position

The classic infinite scroll complaint: you scroll through 500 icons, open one, press Back, and land at the top with only the first 96 rendered. The browser can't restore a scroll position that doesn't exist yet in the freshly rendered page.

Ways to fix it:

  • Keep the count in the URL, such as ?shown=288, updated with history.replaceState as batches load. On return, render that many before the browser restores the scroll position.
  • Store the count in sessionStorage, keyed by the current query, if you'd rather keep the URL clean.
  • Benefit from the back/forward cache. Browsers can keep a whole page in memory and restore it exactly on Back, but only when the page is eligible; pages with unload handlers, for example, often aren't. Don't rely on it alone.

In a single-page app, client-side routing may keep the gallery mounted, which avoids the problem entirely, but check what your router actually does.

Show more as a fallback

For an icon gallery, a good default combines automatic loading for people who scroll with a visible button for everyone else. The button gives keyboard users an explicit control and covers any case where automatic loading doesn't trigger.

import { useEffect, useRef } from 'react'

type Props = {
  shown: number
  total: number
  onMore: (fromButton: boolean) => void
}

export function LoadMore({ shown, total, onMore }: Props) {
  const sentinel = useRef<HTMLDivElement>(null)

  useEffect(() => {
    const el = sentinel.current
    if (el === null || shown >= total) return
    const observer = new IntersectionObserver(
      ([entry]) => {
        if (entry.isIntersecting) onMore(false)
      },
      { rootMargin: '600px 0px' },
    )
    observer.observe(el)
    return () => observer.disconnect()
  }, [shown, total, onMore])

  if (shown >= total) return null
  return (
    <div ref={sentinel}>
      <button type="button" onClick={() => onMore(true)}>
        Show more ({total - shown} left)
      </button>
    </div>
  )
}

The fromButton flag lets the parent move focus to the first new item only when someone pressed the button. Reset the count when the search or filter changes, and show the total, for example "Showing 192 of 2,140", so people know how much is left.

Which to choose

  • A searchable icon gallery sorted by popularity: automatic loading plus a "Show more" button, with the count kept in the URL.
  • A gallery where people cite positions, or long category listings you want crawled page by page: pagination with a URL per page.
  • A small set of a few hundred icons: render them all and skip the question. Rendering thousands of icons explains when that stops being cheap.

More in Performance

All guides