Pagination & Infinite Scroll
Pagination & Infinite Scroll
8 reglasPaginación para tareas goal-directed; scroll infinito solo para feeds
La elección entre paginación y scroll infinito es una decisión de intención, no de estética. La paginación impone páginas discretas que actúan como marcadores: el usuario puede decir "estaba en la página 4" y volver con un clic, lo que es indispensable en tareas dirigidas a un objetivo como buscar un producto, comparar precios o revisar resultados. El scroll infinito elimina esas anclas y desorienta al usuario, que no sabe cuánto falta ni adónde volver; Nielsen Norman Group lo recomienda únicamente para contenido homogéneo que se explora sin objetivo concreto, como feeds sociales o entretenimiento. Usar scroll infinito en una búsqueda de resultados penaliza directamente el rendimiento de la tarea.
Nielsen Norman Group "Infinite Scrolling: When to Use It" (nngroup.com/videos/infinite-scrolling-when) · Baymard Institute (vía Smashing Magazine 2016)"Load more" como híbrido superior en listas de productos
El botón "Load more" combina la fluidez del scroll continuo con el control consciente del usuario: el siguiente bloque aparece cuando el usuario lo pide, no de forma automática. Esto le permite consolidar la lista visible, comparar artículos dentro de ella y acceder al footer en cualquier momento. En el benchmark de e-commerce de Baymard, "Load more" combinado con lazy-loading resultó la implementación superior: los usuarios exploraron más productos que con paginación pero mantuvieron la atención enfocada en cada ítem, a diferencia del scroll infinito automático que produce exploración superficial. Como criterio de oportunidad, muy pocos de los líderes benchmarkeados lo usaban, así que adoptarlo bien diferencia.
Baymard Institute "Load More vs. Pagination vs. Infinite Scrolling" (baymard.com/blog/external-load-more-vs-pagination-vs-infinite-scrolling) · Smashing Magazine 2016Nunca uses scroll infinito automático en páginas con footer funcional
El scroll infinito inyecta contenido nuevo justo antes de que el footer entre en el viewport, haciendo físicamente imposible llegar a él con el ratón o el touch. Los footers suelen contener contacto, términos legales, newsletter, accesos secundarios de navegación y a veces formularios de conversión; bloquear ese acceso no es un trade-off menor, sino que cuesta conversiones y genera frustración medible. NN Group documenta que "el flujo constante de contenido impide que los usuarios lleguen a la información útil normalmente alojada en el footer". Si la página tiene un footer con valor, el patrón correcto es un "Cargar más" explícito que, al agotar el contenido, deja aparecer el footer con normalidad.
Nielsen Norman Group "Infinite Scrolling Tips" (nngroup.com/articles/infinite-scrolling-tips) · Etsy revirtió scroll infinito (Inside NewCity)Restaura la posición exacta al volver atrás con history API
Cuando un usuario entra a un detalle y vuelve al listado con el botón Atrás, espera encontrarse exactamente donde estaba; sin restauración de posición el navegador lo regresa al top y debe re-scrollear todo lo ya visto, lo cual es especialmente grave en listas con "Load more" donde ese contenido ya no está montado. Baymard mide que el 59% de los sitios falla al menos una de las cuatro expectativas del botón Atrás, y que el 13% no devuelve al usuario al mismo lugar del listado. La solución es history.scrollRestoration = "manual" más guardar la posición o el ítem activo en sessionStorage (o history.pushState) y restaurarla al volver.
Anuncia el contenido nuevo con aria-live y mueve el foco al cargar
Cuando el scroll infinito o un "Load more" inyectan nodos nuevos al DOM, los lectores de pantalla no los detectan automáticamente a menos que exista una región aria-live; sin ese anuncio, el usuario ciego simplemente no sabe que apareció contenido. WCAG 2.1.1 (nivel A) exige que toda la funcionalidad sea operable por teclado, lo que implica que los nuevos ítems sean alcanzables con Tab. El patrón completo es: una región aria-live="polite" que anuncia "12 artículos nuevos cargados, 84 restantes", y mover el foco al primer ítem nuevo tras activar "Load more" con teclado, para que la navegación lineal continúe sin perder el hilo.
"12 artículos nuevos cargados, 84 restantes"
Indica siempre cuántos resultados se muestran del total
Sin contexto de progreso el usuario no puede juzgar el esfuerzo que requiere revisar todo el catálogo ni decidir si vale la pena refinar los filtros. El texto "Mostrando 1-24 de 340 productos" da dos anclas cognitivas: cuánto ha visto y cuánto falta. NN Group advierte que la ausencia de este indicador genera la "ilusión de completitud", donde el usuario cree haber visto todos los resultados cuando solo vio el primer bloque. El indicador es obligatorio tanto en paginación (rango activo "Resultados 41-60 de 340") como en "Load more" (junto al botón o encima de él, idealmente con un contador decreciente).
Nielsen Norman Group "Infinite Scrolling: When to Use It" · Smashing Magazine "Pagination, Infinite Scrolling and Load More" (2016)Paginación accesible: nav, aria-current="page" y targets ≥24px
La paginación es navegación de página, no decoración: envolverla en un <nav aria-label="Paginación"> la convierte en un landmark reconocible para lectores de pantalla. El ítem activo debe llevar aria-current="page" (no solo una clase CSS) para que el lector lo anuncie explícitamente; aria-selected es incorrecto en este contexto. Cada enlace necesita texto visible o un aria-label descriptivo ("Ir a la página 5") y un área de toque que cumpla WCAG 2.5.8 (mínimo 24×24 px, nivel AA), idealmente los 44×44 px de las guías de iOS. La estructura semántica debe transmitir la misma información que la presentación visual (WCAG 1.3.1).
Virtualiza listas largas para mantener el DOM bajo ~1500 nodos
Montar miles de nodos en el DOM degrada el rendimiento del scroll, aumenta el tiempo de pintado y consume memoria innecesaria, sobre todo en móvil. La virtualización (windowing) renderiza solo los ítems visibles en el viewport más un pequeño buffer, destruyendo y recreando nodos al vuelo según la posición de scroll; esto permite scroll infinito o listas muy largas sin sacrificar fluidez. Lighthouse marca como excesivo un DOM con más de ~1500 nodos totales, profundidad máxima de 32, o un padre con más de 60 hijos. La paginación clásica resuelve lo mismo por otra vía: nunca monta el contenido de las otras páginas. Librerías como react-window, @tanstack/react-virtual o react-virtuoso implementan el windowing.
Google Lighthouse "Avoid an excessive DOM size" (developer.chrome.com/docs/lighthouse/performance/dom-size) · react-window / @tanstack/react-virtual- R-656 Paginación para tareas goal-directed; scroll infinito solo para feeds
- R-657 "Load more" como híbrido superior en listas de productos
- R-658 Nunca uses scroll infinito automático en páginas con footer funcional
- R-659 Restaura la posición exacta al volver atrás con history API
- R-660 Anuncia el contenido nuevo con aria-live y mueve el foco al cargar
- R-661 Indica siempre cuántos resultados se muestran del total
- R-662 Paginación accesible: nav, aria-current="page" y targets ≥24px
- R-663 Virtualiza listas largas para mantener el DOM bajo ~1500 nodos