Media lightbox
Media lightbox
8 reglasTrata el lightbox como un dialog modal: role, aria-modal y foco atrapado
Un lightbox es, semanticamente, un dialog modal: aparece sobre el contenido principal, lo bloquea y exige interacción antes de continuar. El patrón oficial WAI-ARIA APG Dialog Modal pide que el contenedor declare role="dialog", aria-modal="true" y un nombre accesible vía aria-labelledby o aria-label. Sin estos atributos el lector de pantalla no distingue el lightbox del resto del DOM y deja al usuario navegar por el fondo. Importante: aria-modal solo informa a la tecnologia asistiva; la captura real del foco se implementa con JavaScript.
Escape cierra el lightbox y el foco regresa al thumbnail que lo abrio
Cuando el usuario pulsa Escape, el lightbox debe cerrarse de inmediato y el foco debe volver al elemento que disparo la apertura (el thumbnail o botón de la galeria). Este comportamiento es obligatorio en el patrón Dialog Modal del APG y evita que los usuarios de teclado queden perdidos en el DOM al cerrar el overlay. Sin retorno de foco, el cursor cae al inicio del documento y obliga a retabular toda la galeria. La única excepción: si el disparador ya no existe en el DOM, se elige un punto lógico alternativo.
W3C WAI-ARIA APG · Dialog (Modal) · codeaccessible.com LightboxNavega con flechas y swipe, y muestra siempre la posición actual
Un lightbox de galeria no es un dialog estático: el usuario espera moverse entre imagenes. ArrowLeft/ArrowRight deben ir a la imagen anterior/siguiente, y Tab/Shift+Tab deben ciclar entre los controles del overlay (anterior, siguiente, cerrar). En móvil, el swipe horizontal es el gesto canonico de navegación, implementado de forma nativa por bibliotecas como PhotoSwipe y SwipeBox. Un indicador de posición tipo "3 / 12" es imprescindible para que el usuario sepa cuantas imagenes faltan y decida si continuar.
W3C WAI-ARIA APG Dialog · PhotoSwipe · SwipeBoxPermite zoom y paneo de la imagen ampliada
La razón de ser de un lightbox es ver el detalle de una imagen que en el thumbnail era pequeña. Sin zoom, el lightbox es solo un visor más grande y el usuario no puede inspeccionar detalles. La implementación moderna usa transform: scale() acelerado por GPU para un zoom suave, y eventos pointermove para el paneo con drag; en móvil, pinch-to-zoom es el estandar. Detalle critico: al detectar un pinch de dos dedos, el handler de paneo debe suprimirse (if (e.touches?.length >= 2) return;) para que la imagen no se desplace mientras se hace zoom.
Botón de cierre prominente (≥ 44×44 px) y cierre por clic en el backdrop
El lightbox debe ofrecer dos mecanismos de cierre: un botón "X" explicito y el clic fuera del contenido, en el backdrop semitransparente. El botón de cierre debe cumplir WCAG 2.5.5 con un área tactil mínima de 44×44 CSS px; el icono visual puede ser más pequeño si el padding del área de clic es suficiente. El clic en el backdrop es un modelo mental establecido: ver contenido oscuro alrededor del lightbox se percibe como "área para salir". Ambos mecanismos deben coexistir; eliminar cualquiera aumenta la fricción de salida.
WCAG 2.5.5 Target Size (AAA) · WCAG 2.5.8 (24px, AA) · CSS-TricksExpon el alt text o caption de la imagen ampliada
Cuando una imagen se amplia en el lightbox, su descripción (alt text o caption) debe ser visible para usuarios de lector de pantalla y también para usuarios videntes que buscan contexto. La practica recomendada es usar <figcaption> dentro de un <figure>: crea la asociación semántica entre imagen y descripción que el lector anuncia automáticamente; como alternativa, aria-describedby apuntando a un párrafo. Colocar el texto debajo de la imagen en una barra de caption es preferible a un overlay encima, que puede generar anuncios confusos.
Carga la imagen grande bajo demanda, no precargues toda la galeria
Las galerias pueden tener decenas de imagenes. Precargar todas en alta resolución al montar la página desperdicia ancho de banda y ralentiza el LCP. La practica correcta: el thumbnail usa la imagen a baja resolución (src pequeño) y, al abrir el lightbox de esa imagen, se carga el src a resolución completa en ese momento. La carga bajo demanda con loading="lazy" nativo o con Intersection Observer evita descargar imagenes en alta resolución que el usuario nunca llega a abrir, reduciendo la transferencia en la primera carga.
Respeta prefers-reduced-motion y bloquea el scroll del fondo
Las transiciones de slide o zoom al abrir o navegar el lightbox pueden provocar nauseas, mareo o desorientación en usuarios con trastornos vestibulares. La solución es aplicar @media (prefers-reduced-motion: reduce) para eliminar o sustituir la animación por un fade simple; el W3C documenta esta técnica como suficiente para WCAG 2.3.3. Por separado, mientras el lightbox esta abierto el scroll del body debe bloquearse para evitar el "scroll bleed". En iOS Safari, overflow: hidden solo no basta: se requiere position: fixed en el body o una libreria body-scroll-lock.
- R-775 Trata el lightbox como un dialog modal: role, aria-modal y foco atrapado
- R-776 Escape cierra el lightbox y el foco regresa al thumbnail que lo abrio
- R-777 Navega con flechas y swipe, y muestra siempre la posición actual
- R-778 Permite zoom y paneo de la imagen ampliada
- R-779 Botón de cierre prominente (≥ 44×44 px) y cierre por clic en el backdrop
- R-780 Expon el alt text o caption de la imagen ampliada
- R-781 Carga la imagen grande bajo demanda, no precargues toda la galeria
- R-782 Respeta prefers-reduced-motion y bloquea el scroll del fondo