Pagination
Pattern de navegación paginada con variantes numéricas, controles de avance, resumen de resultados y selectores auxiliares.
1. Paginación Numérica Básica
Mostrar HTML
<nav class="gn-pagination" aria-label="Navegación de páginas">
<div class="gn-pagination__nav">
<ul class="gn-pagination__list">
<li class="gn-pagination__item"><a href="#" class="gn-pagination__link gn-pagination__link--current" aria-current="page">1</a></li>
<li class="gn-pagination__item"><a href="#" class="gn-pagination__link">2</a></li>
<li class="gn-pagination__item"><a href="#" class="gn-pagination__link">3</a></li>
</ul>
</div>
</nav>
2. Controles de Avance y Foco Visible
Mostrar HTML
<nav class="gn-pagination" aria-label="Navegación de resultados">
<div class="gn-pagination__nav">
<a href="#" class="gn-pagination__button gn-pagination__button--icon" aria-label="Página anterior">
<svg focusable="false" viewBox="0 0 24 24" fill="currentColor" width="20" height="20" aria-hidden="true"><path d="M15.41 16.59L10.83 12l4.58-4.59L14 6l-6 6 6 6 1.41-1.41z"/></svg>
</a>
<ul class="gn-pagination__list">
<li class="gn-pagination__item"><a href="#" class="gn-pagination__link gn-pagination__link--current" aria-current="page">1</a></li>
<li class="gn-pagination__item"><a href="#" class="gn-pagination__link is-focus">2</a></li>
<li class="gn-pagination__item"><a href="#" class="gn-pagination__link">3</a></li>
</ul>
<a href="#" class="gn-pagination__button gn-pagination__button--icon" aria-label="Página siguiente">
<svg focusable="false" viewBox="0 0 24 24" fill="currentColor" width="20" height="20" aria-hidden="true"><path d="M8.59 16.59L13.17 12 8.59 7.41 10 6l6 6-6 6-1.41-1.41z"/></svg>
</a>
</div>
</nav>
3. Paginación con Ellipsis
Mostrar HTML
<nav class="gn-pagination" aria-label="Catálogo de productos">
<div class="gn-pagination__nav">
<a href="#" class="gn-pagination__button gn-pagination__button--icon" aria-label="Página anterior">
<svg focusable="false" viewBox="0 0 24 24" fill="currentColor" width="20" height="20" aria-hidden="true"><path d="M15.41 16.59L10.83 12l4.58-4.59L14 6l-6 6 6 6 1.41-1.41z"/></svg>
</a>
<ul class="gn-pagination__list">
<li class="gn-pagination__item"><a href="#" class="gn-pagination__link">1</a></li>
<li class="gn-pagination__item"><span class="gn-pagination__link gn-pagination__link--ellipsis" aria-hidden="true">...</span></li>
<li class="gn-pagination__item"><a href="#" class="gn-pagination__link">4</a></li>
<li class="gn-pagination__item"><a href="#" class="gn-pagination__link gn-pagination__link--current" aria-current="page">5</a></li>
<li class="gn-pagination__item"><a href="#" class="gn-pagination__link">6</a></li>
<li class="gn-pagination__item"><span class="gn-pagination__link gn-pagination__link--ellipsis" aria-hidden="true">...</span></li>
<li class="gn-pagination__item"><a href="#" class="gn-pagination__link">10</a></li>
</ul>
<a href="#" class="gn-pagination__button gn-pagination__button--icon" aria-label="Página siguiente">
<svg focusable="false" viewBox="0 0 24 24" fill="currentColor" width="20" height="20" aria-hidden="true"><path d="M8.59 16.59L13.17 12 8.59 7.41 10 6l6 6-6 6-1.41-1.41z"/></svg>
</a>
</div>
</nav>
4. Botones Deshabilitados y Resumen de Resultados
Mostrar HTML
<nav class="gn-pagination" aria-label="Listado de noticias">
<div class="gn-pagination__nav">
<button type="button" class="gn-pagination__button gn-pagination__button--icon" aria-label="Página anterior" disabled>
<svg focusable="false" viewBox="0 0 24 24" fill="currentColor" width="20" height="20" aria-hidden="true"><path d="M15.41 16.59L10.83 12l4.58-4.59L14 6l-6 6 6 6 1.41-1.41z"/></svg>
</button>
<ul class="gn-pagination__list">
<li class="gn-pagination__item"><a href="#" class="gn-pagination__link gn-pagination__link--current" aria-current="page">1</a></li>
<li class="gn-pagination__item"><a href="#" class="gn-pagination__link">2</a></li>
</ul>
<a href="#" class="gn-pagination__button gn-pagination__button--icon" aria-label="Página siguiente">
<svg focusable="false" viewBox="0 0 24 24" fill="currentColor" width="20" height="20" aria-hidden="true"><path d="M8.59 16.59L13.17 12 8.59 7.41 10 6l6 6-6 6-1.41-1.41z"/></svg>
</a>
</div>
<div class="gn-pagination__summary" aria-live="polite">
1-25 de 100
</div>
</nav>
5. Selector de Página Interno (Con Texto Anterior/Siguiente)
El patrón reutiliza estructuralmente un componente select en el centro de la navegación.
Mostrar HTML
<nav class="gn-pagination" aria-label="Archivos">
<div class="gn-pagination__nav">
<a href="#" class="gn-pagination__button gn-pagination__button--nav">
<svg focusable="false" class="gn-pagination__icon" viewBox="0 0 24 24" fill="currentColor" width="20" height="20" aria-hidden="true"><path d="M15.41 16.59L10.83 12l4.58-4.59L14 6l-6 6 6 6 1.41-1.41z"/></svg>
Anterior
</a>
<div class="gn-select gn-select--sm gn-pagination__select">
<label for="page-selector" class="gn-select__label sr-only">Ir a la página</label>
<select id="page-selector" class="gn-select__control">
<option value="1">1</option>
<option value="2" selected>2</option>
<option value="3">3</option>
</select>
</div>
<a href="#" class="gn-pagination__button gn-pagination__button--nav gn-pagination__button--nav-next">
Siguiente
<svg focusable="false" class="gn-pagination__icon" viewBox="0 0 24 24" fill="currentColor" width="20" height="20" aria-hidden="true"><path d="M8.59 16.59L13.17 12 8.59 7.41 10 6l6 6-6 6-1.41-1.41z"/></svg>
</a>
</div>
<div class="gn-pagination__summary" aria-live="polite">
26-50 de 250
</div>
</nav>
6. Configuración Compleja: Items por Página + Resumen
Variante con numeración de páginas entre los controles de Anterior y Siguiente, sin selector central.
Mostrar HTML
<nav class="gn-pagination" aria-label="Resultados paginados">
<div class="gn-pagination__nav">
<a href="#" class="gn-pagination__button gn-pagination__button--nav">
<svg focusable="false" class="gn-pagination__icon" viewBox="0 0 24 24" fill="currentColor" width="20" height="20" aria-hidden="true"><path d="M15.41 16.59L10.83 12l4.58-4.59L14 6l-6 6 6 6 1.41-1.41z"/></svg>
Anterior
</a>
<ul class="gn-pagination__list">
<li class="gn-pagination__item"><a href="#" class="gn-pagination__link">1</a></li>
<li class="gn-pagination__item"><a href="#" class="gn-pagination__link gn-pagination__link--current" aria-current="page">2</a></li>
<li class="gn-pagination__item"><a href="#" class="gn-pagination__link">3</a></li>
<li class="gn-pagination__item"><a href="#" class="gn-pagination__link">4</a></li>
</ul>
<a href="#" class="gn-pagination__button gn-pagination__button--nav gn-pagination__button--nav-next">
Siguiente
<svg focusable="false" class="gn-pagination__icon" viewBox="0 0 24 24" fill="currentColor" width="20" height="20" aria-hidden="true"><path d="M8.59 16.59L13.17 12 8.59 7.41 10 6l6 6-6 6-1.41-1.41z"/></svg>
</a>
</div>
<div class="gn-pagination__summary" aria-live="polite">
26-50 de 100
</div>
</nav>
7. Configuración Compleja: Items por Página + Resumen
Mostrar HTML
<nav class="gn-pagination" aria-label="Tabla de datos">
<div class="gn-pagination__nav">
<a href="#" class="gn-pagination__button gn-pagination__button--icon" aria-label="Página anterior">
<svg focusable="false" viewBox="0 0 24 24" fill="currentColor" width="20" height="20" aria-hidden="true"><path d="M15.41 16.59L10.83 12l4.58-4.59L14 6l-6 6 6 6 1.41-1.41z"/></svg>
</a>
<ul class="gn-pagination__list">
<li class="gn-pagination__item"><a href="#" class="gn-pagination__link">1</a></li>
<li class="gn-pagination__item"><a href="#" class="gn-pagination__link gn-pagination__link--current" aria-current="page">2</a></li>
</ul>
<a href="#" class="gn-pagination__button gn-pagination__button--icon" aria-label="Página siguiente">
<svg focusable="false" viewBox="0 0 24 24" fill="currentColor" width="20" height="20" aria-hidden="true"><path d="M8.59 16.59L13.17 12 8.59 7.41 10 6l6 6-6 6-1.41-1.41z"/></svg>
</a>
</div>
<div class="gn-pagination__controls">
<div class="gn-pagination__selector">
<label for="items-selector" class="gn-pagination__selector-label">Items por página</label>
<div class="gn-select gn-select--sm gn-pagination__select">
<select id="items-selector" class="gn-select__control">
<option value="25" selected>25</option>
<option value="50">50</option>
<option value="100">100</option>
</select>
</div>
</div>
<div class="gn-pagination__summary" aria-live="polite">
26-50 de 250
</div>
</div>
</nav>
Pagination Pattern
El Pagination es un patrón de diseño que proporciona navegación estructurada a través de un conjunto de datos grande que ha sido dividido en múltiples páginas o vistas, mejorando el rendimiento y facilitando la asimilación de la información por parte de los usuarios.
¿Por qué es un Pattern?
La paginación no se concibe como un control unitario aislado, sino como una composición estructural que articula piezas independientes:
- Controles de navegación de avance y retroceso (Flechas o Botones con texto).
- Enlaces numéricos de salto directo (
<a>o<button>). - Textos pasivos de resumen de métricas ("1-25 de 100").
- Controles auxiliares como selectores de salto de página o cambio de densidad de resultados por página, que integran internamente el componente base
gn-select.
Cuándo usarlo
- En tablas de datos densas, listas de resultados de búsqueda o catálogos de productos que superen una cantidad manejable de elementos en pantalla (generalmente más de 20-25 items).
- Para dividir vistas largas en lugar de usar un *scroll infinito* si se requiere que el usuario sepa la cantidad total de resultados y pueda acceder directamente a un segmento específico.
Opciones de Implementación Semántica
El patrón expone los ejemplos usando fundamentalmente enlaces (<a>), pero la decisión final debe basarse en la arquitectura técnica de tu aplicación:
- Usa enlaces (
<a>): Si al cambiar de página se genera una recarga completa del documento o la URL se actualiza (ej:?page=2). Esto es vital para el SEO y para permitir a los usuarios "Abrir en nueva pestaña" o guardar marcadores. - Usa botones (
<button>): Exclusivamente si la paginación inyecta la nueva vista dinámicamente mediante JavaScript (ej: llamadas AJAX o un SPA sin control estricto de historial del navegador). En los ejemplos demostrativos, se han usado botones para los estados *disabled*, pero aplican los mismos principios.
Estados y Tratamiento de la Página Actual
- La página actualmente seleccionada resalta visualmente (
color: var(--gn-color-link-focus)y mayor peso tipográfico) usando la clase.gn-pagination__link--current. - Semánticamente se añade el atributo
aria-current="page"al enlace activo, informando a los lectores de pantalla de que se trata del contexto actual. - Los elementos colindantes omitidos para acortar largas listas se representan mediante
.gn-pagination__link--ellipsis, el cual hereda la estética por defecto pero sin comportamiento de hover.
Integración con Componentes Auxiliares
El patrón contempla el uso nativo de selectores, como ir a una página concreta o alterar la cantidad de items. Para ello simplemente se embebe el componente gn-select dentro de los bloques .gn-pagination__nav o .gn-pagination__controls. El CSS del patrón aplica modificaciones sutiles de layout y márgenes para asegurar que encaje en altura (35px) y armonía visual con los botones de paginación vecinos.
Accesibilidad Adicional
- El contenedor principal se define como
<nav aria-label="Navegación de resultados">para declararse explícitamente en el árbol de navegación accesibilidad. - El resumen de totales incluye
aria-live="polite"en el caso de las implementaciones dinámicas (JS), de forma que el lector de pantalla anuncie transparentemente el nuevo rango al cambiar de página.