Saltar al contenido principal
Sábado 31 Enero - Taller en vivo: Herramientas reales para analizar accesibilidad.¡Apúntate ya!
Volver a la página del blog

¿Cómo hacer carruseles accesibles sin morir en el intento?

Tiempo de lectura: 15 minutos
Autor
Carlos Garrido Marín
Fecha de publicación
10 / 01 / 2026

Estás navegando por la web de tu tienda favorita. Ves un banner con una oferta increíble, pero antes de poder hacer clic... desaparece. Aparece otro. Y otro. Es como intentar subir a un tren en marcha: si no eres lo suficientemente rápido, te quedas en el andén. Ahora imagina que además de esa carrera contra el tiempo, no puedes ver la pantalla y dependes de un lector de pantalla que te va narrando lo que hay. El carrusel cambia sin avisar, el lector empieza a leer algo nuevo antes de terminar lo anterior, y tú no tienes ni idea de dónde estás ni cómo volver a esa oferta que te interesaba. 

Esta es la realidad diaria de millones de usuarios. Y no hablamos de un componente marginal: los carruseles están en prácticamente todas las páginas de inicio de e-commerce, portales de noticias y landing pages. Según un estudio de Nielsen Norman Group, solo el 1% de los usuarios hacen clic en un carrusel, y de esos clics, el 84% son en el primer slide. El contenido que no está en el primer slide prácticamente no existe. Pero el problema va más allá de las estadísticas de clics: para usuarios que dependen de tecnologías de asistencia, un carrusel mal implementado puede ser directamente imposible de usar.

En este artículo vamos a sumergirnos en el mundo de los carruseles accesibles. Veremos los diferentes tipos que existen, por qué son problemáticos desde el punto de vista de la accesibilidad, cómo las WCAG nos orientan para implementarlos correctamente y, sobre todo, cómo puedes crear carruseles que funcionen para todos los usuarios.

Tipos de carruseles y sus retos de accesibilidad

Antes de entrar en materia, es importante entender que no todos los carruseles son iguales. Dependiendo de su complejidad y comportamiento, los retos de accesibilidad varían:

Carrusel de contenido con navegación manual

Slides que el usuario navega manualmente con botones de anterior/siguiente. Es el más común en galerías de productos o testimonios. No rota automáticamente, pero oculta contenido. El usuario tiene el control total de cuándo avanzar.

Carrusel con rotación automática

El más problemático. Los slides cambian solos cada determinados segundos. Es típico en banners promocionales de páginas de inicio. Aquí es donde la mayoría de problemas de accesibilidad se concentran: el contenido desaparece antes de que el usuario pueda leerlo o interactuar con él.

Carrusel infinito

Los slides se repiten en bucle sin principio ni fin aparente. Puede ser manual o automático. Añade una capa extra de complejidad para usuarios de tecnologías de asistencia porque no hay un "final" claro: ¿cómo sabe el usuario cuántos elementos hay? ¿Cómo sabe si ya los ha visto todos? Los lectores de pantalla pueden quedar atrapados en un bucle infinito de contenido repetido.

Vamos a ver cada uno de estos casos a lo largo del artículo, pero primero entendamos por qué los carruseles son problemáticos.

¿Por qué los carruseles son un problema de accesibilidad?

Los carruseles son uno de los componentes más utilizados en diseño web moderno. Los encontramos en prácticamente todas las páginas de inicio de e-commerce, portales de noticias y landing pages. Sin embargo, también son uno de los elementos más problemáticos desde el punto de vista de la accesibilidad.

Cuando un carrusel oculta contenido, ya sea con rotación automática o no, ciertos usuarios tienen dificultades para acceder a él. Las personas con discapacidades cognitivas necesitan más tiempo para procesar la información, mientras que los usuarios de lectores de pantalla a menudo no saben que hay más contenido oculto. De manera similar, las personas con baja visión requieren tiempo adicional para identificar elementos visuales, y los usuarios con discapacidades motoras tardan más en interactuar con los controles.

Imagina que estás navegando con el teclado y llegas a un enlace dentro del carrusel. Justo cuando vas a activarlo, el slide cambia y el foco se pierde o, peor aún, se queda en un elemento que ya no es visible y no sabes donde estás.

Sin controles adecuados, los usuarios de teclado y tecnologías de asistencia no tienen forma de navegar entre slides de forma fácil, saber cuántos slides hay y en cuál se encuentran, volver a un slide anterior que les interesó, o pausar la rotación (si la hay) para leer el contenido.

¿Qué dicen las WCAG sobre los carruseles?

Las WCAG no tienen un criterio específico llamado "carruseles accesibles", pero varios criterios se aplican directamente a este componente. Veamos los más relevantes:

Criterio 1.3.1 - Información y relaciones (Nivel A)

La estructura y las relaciones del contenido deben ser programáticamente determinables. En el contexto de carruseles, esto significa que:

  • Los usuarios deben poder identificar que están interactuando con un carrusel.
  • Debe ser claro cuántos elementos contiene el carrusel.
  • Debe indicarse qué elemento está actualmente visible.

Criterio 4.1.2 - Nombre, función, valor (Nivel A)

Todos los componentes de la interfaz deben tener un nombre accesible, su función debe ser identificable, y su estado actual debe comunicarse a las tecnologías de asistencia.

Criterio 2.1.1 - Teclado (Nivel A)

Toda la funcionalidad del carrusel debe ser operable mediante teclado, sin requerir tiempos específicos para pulsaciones individuales.

Criterio 2.2.2 - Pausar, detener, ocultar (Nivel A)

Este criterio aplica específicamente a carruseles con rotación automática. Establece que para cualquier contenido que se mueva automáticamente durante más de 5 segundos, debe existir un mecanismo para pausar, detener u ocultar dicho contenido.

Ejemplo: Carrusel de productos con múltiples elementos visibles

Este es probablemente el carrusel más común en e-commerce: una fila de productos donde se muestran varios a la vez (típicamente 3-4 en escritorio, 1-2 en móvil) y cada uno tiene su propio enlace o CTA (Click to Action). Es el típico "Productos relacionados" o "Los clientes también compraron".

Este tipo de carrusel presenta un reto especial de accesibilidad: hay elementos interactivos (enlaces, botones) que están parcialmente visibles o completamente ocultos, pero siguen siendo alcanzables por teclado. Imagina que estás navegando con Tab y de repente el foco se va a un enlace que no puedes ver, desorientador, ¿verdad?

Versión inaccesible

Vamos a verlo en vivo. Navega con Tab y observa qué pasa cuando llegas a los productos que no están visibles:

Smartphone - 99€

Ver producto

Portátil - 599€

Ver producto

Auriculares - 79€

Ver producto

Tablet - 299€

Ver producto

Smartwatch - 199€

Ver producto

Cámara - 449€

Ver producto

¿Has probado a navegar con Tab? Cuando llegas al cuarto, quinto y sexto producto, el foco se mueve a elementos que no puedes ver. Esto es muy confuso. Además, los botones de navegación son <span> (no accesibles por teclado).

El problema de los elementos ocultos pero focusables

Aquí es donde entra en juego una decisión importante de diseño: ¿qué hacemos con los elementos interactivos que están fuera de la vista?

Tenemos dos estrategias principales:

Opción 1: Usar el atributo inert

El atributo inert es relativamente nuevo y hace exactamente lo que necesitamos: desactiva completamente un elemento y todos sus descendientes para la interacción. Los elementos con inert:

  • No son focusables con teclado.
  • No son anunciados por lectores de pantalla.
  • No responden a clics ni interacción por ratón.

La gran ventaja de inert es que el usuario no tiene que recorrer todos los elementos del carrusel para llegar al siguiente componente de la página.

Por ejemplo, en un carrusel con 20 productos sin inert el usuario de teclado tendría que pulsar Tab 20 veces (o más, si cada producto tiene varios elementos interactivos) solo para pasar el carrusel. Con inert, solo los productos visibles son focusables, y el usuario decide activamente si quiere ver más productos usando los botones de navegación. Es él quien tiene el control de explorar o pasar de largo.

<!-- Los productos fuera de vista tienen inert -->
<div class="producto" inert>
  <img src="tablet.jpg" alt="">
  <p>Tablet Samsung Galaxy Tab 299€</p>
  <a href="/producto/4">Ver producto</a>
</div>

Lenguaje del código:HTML

Opción 2: Scroll automático al recibir foco

Otra estrategia es hacer scroll automático para que el elemento enfocado siempre sea visible. Esto tiene la ventaja de que el usuario puede navegar por todos los productos sin usar los botones de navegación, pero la desventaja de que obliga a pasar por todos los elementos.

Esto se puede conseguir de manera muy sencilla con un poco de Javascript siempre y cuando nuestro carousel no depende de implementaciones de transformaciones de CSS: 

product.addEventListener("focusin", () => {
  product.scrollIntoView({
    behavior: "smooth",
    block: "nearest",
  });
});

Lenguaje del código:JavaScript

Versión accesible

Ahora vamos a ver una posible solución accesible. Lo primero que hay que tener en cuenta es que no existe una única manera de hacer este carrusel accesible. Como hemos visto antes, existen diferentes formas y técnicas para resolver los problemas que generan.

En este caso, se han tomado dos decisiones importantes. La primera es utilizar el atributo inert para las slides ocultas, de manera que el usuario navegue por el carrusel exclusivamente a través de las flechas. La segunda decisión tiene que ver con el comportamiento al llegar al final del carrusel: cuando el usuario está en alguno de los botones de navegación y alcanza el extremo, el foco se traslada automáticamente a la flecha contraria. Por ejemplo, si estás en la flecha de siguiente y llegas a la última slide, el foco se moverá a la flecha de anterior.

Esta última decisión podría generar debate sobre si es o no la mejor alternativa. No obstante, según mi experiencia y la opinión de algunos usuarios nativos de lector de pantalla (quienes podrían ser los más afectados por esta decisión), no les parece una mala solución, ya que les deja justo al principio del contenedor de la slide. Además, es la misma solución que utiliza Microsoft en su sistema de diseño Fluent 2, donde puedes encontrar un ejemplo de carousel accesible de Microsoft en Fluent 2.

La otra alternativa sería añadir el atributo aria-disabled="true" sobre los botones cuando llegan al final y el usuario tiene el foco sobre ellos. De esta manera, no se les movería el foco y se les notificaría que el botón está deshabilitado.

Vamos a verlo en funcionamiento:

¿Ves la diferencia? Ahora cuando navegas con Tab, solo los productos visibles reciben foco. Los productos ocultos tienen el atributo inert, así que ni el teclado ni los lectores de pantalla pueden llegar a ellos hasta que uses los controles de navegación para mostrarlos.

Prueba a navegar hasta el final: cuando llegues a la última posición con el foco en el botón "siguiente", observa cómo el foco salta automáticamente al botón "anterior". Esta pequeña decisión de diseño evita que el usuario pierda la referencia de dónde está.

También, podemos ver como se anuncia a través del lector de pantalla en el siguiente video:

Desglose de los atributos ARIA utilizados

Vamos a analizar cada atributo ARIA que hemos usado en este carrusel:

  • aria-roledescription="carrusel": Personaliza cómo el lector de pantalla describe el componente. En lugar de "región" o "sección", dirá "carrusel".
  • aria-label="Productos relacionados": Da contexto sobre qué contiene el carrusel.
  • role="group" con aria-roledescription="slide": Agrupa el conjunto de productos visibles como un "slide" del carrusel.
  • aria-label="Productos 1 a 3 de 6": Indica la posición actual dentro del carrusel. Se actualiza dinámicamente cuando el usuario navega.
  • inert: Desactiva completamente los productos que no están visibles. No reciben foco, no son leídos por lectores de pantalla, no interfieren.
  • aria-live="polite": Anuncia los cambios cuando el usuario navega a otro grupo de productos. Cuando el contenido dentro del elemento con aria-live cambia, el lector de pantalla lo anuncia automáticamente al usuario. El valor "polite" significa que esperará a que el lector de pantalla termine lo que esté diciendo antes de anunciar el cambio (a diferencia de "assertive", que interrumpiría inmediatamente). En nuestro carrusel, cada vez que el usuario navega a un nuevo grupo de productos, actualizamos el texto de esta región con algo como "Mostrando productos 4 a 6 de 6", y el lector de pantalla lo anuncia sin que el usuario tenga que hacer nada. Sin esta región live, el usuario de lector de pantalla no tendría forma de saber que el contenido ha cambiado al pulsar los botones de navegación.
  • aria-hidden="true" en iconos: Los símbolos decorativos no son leídos.
<section
  aria-roledescription="carrusel"
  aria-label="Productos relacionados"
  class="carousel">
  <div class="carousel__container">
    <button
      type="button"
      aria-label="Ver producto anterior"
      class="carousel__nav"
      disabled>
      <span aria-hidden="true">‹</span>
    </button>

    <div class="carousel__viewport">
      <div
        role="group"
        aria-roledescription="slide"
        aria-label="Productos 1 a 3 de 6"
        class="carousel__track">
        <!-- Productos visibles (1-3): sin inert -->
        <div class="carousel__item">
          <img src="phone.jpg" alt="" />
          <p class="carousel__item-name">
            Smartphone Galaxy X
          </p>
          <p class="carousel__item-price">99€</p>
          <a href="/producto/1">
            Ver detalles del Smartphone
          </a>
        </div>

        <div class="carousel__item">
          <img src="laptop.jpg" alt="" />
          <p class="carousel__item-name">
            Portátil UltraBook Pro
          </p>
          <p class="carousel__item-price">599€</p>
          <a href="/producto/2">
            Ver detalles del Portátil
          </a>
        </div>

        <div class="carousel__item">
          <img src="headphones.jpg" alt="" />
          <p class="carousel__item-name">
            Auriculares SoundMax
          </p>
          <p class="carousel__item-price">79€</p>
          <a href="/producto/3">
            Ver detalles de Auriculares
          </a>
        </div>

        <!-- Productos ocultos (4-6): con inert -->
        <div class="carousel__item" inert>
          <img src="tablet.jpg" alt="" />
          <p class="carousel__item-name">
            Tablet Galaxy Tab
          </p>
          <p class="carousel__item-price">299€</p>
          <a href="/producto/4">Ver detalles de Tablet</a>
        </div>

        <div class="carousel__item" inert>
          <img src="watch.jpg" alt="" />
          <p class="carousel__item-name">
            Smartwatch FitPro
          </p>
          <p class="carousel__item-price">199€</p>
          <a href="/producto/5">
            Ver detalles de Smartwatch
          </a>
        </div>

        <div class="carousel__item" inert>
          <img src="camera.jpg" alt="" />
          <p class="carousel__item-name">Cámara PhotoMax</p>
          <p class="carousel__item-price">449€</p>
          <a href="/producto/6">Ver detalles de Cámara</a>
        </div>
      </div>
    </div>

    <button
      type="button"
      aria-label="Ver producto siguiente"
      class="carousel__nav">
      <span aria-hidden="true">›</span>
    </button>
  </div>

  <div aria-live="polite" class="sr-only"></div>
</section>

Lenguaje del código:HTML

Fíjate en algunos detalles importantes:

  • Las imágenes tienen alt="": son decorativas porque el nombre del producto ya está en el texto. Si pusiéramos el nombre del producto en el alt, los lectores de pantalla lo anunciarían dos veces.
  • Los enlaces tienen textos descriptivos: en lugar de "Ver detalles" genérico, usamos "Ver detalles del Smartphone" para que el usuario sepa a qué producto se refiere sin necesidad de contexto. Esto se podría conseguir también haciendo uso de aria-labelledby.
  • Los botones están posicionados a los lados: esto es importante porque así el orden del DOM coincide con el orden visual.

Cómo implementar la región live para anuncios

La región aria-live, como ya hemos comentado, sirve para que los usuarios de lectores de pantalla entiendan qué está pasando cuando interactúan con el carrusel. Sin ella, al pulsar los botones de navegación, el contenido cambiaría pero el usuario no recibiría ninguna confirmación de que algo ha ocurrido.

En nuestro carrusel, hemos añadido un <div> al final del componente que nos permitirá manejar estos anuncios:

<div aria-live="polite" class="sr-only" />

Lenguaje del código:HTML

El atributo aria-live="polite" le dice a los lectores de pantalla: "cuando el contenido de este elemento cambie, anúncialo al usuario". El valor "polite" significa que no interrumpirá lo que el lector esté diciendo en ese momento, esperará a que termine. En el video mostrado previamente, se puede ver como esto ocurre y espera a anunciar el cambio de slide.

La clase sr-only hace que el elemento sea invisible visualmente pero accesible para lectores de pantalla. Es una técnica muy común en accesibilidad. El CSS que usamos es este:

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border-width: 0;
}

Lenguaje del código:CSS

¿Por qué este CSS tan peculiar? Porque necesitamos que el elemento no ocupe espacio visual ni sea visible, pero que siga existiendo en el DOM para que los lectores de pantalla lo encuentren. Si usáramos display: none o visibility: hidden, el lector de pantalla también lo ignoraría. Esta técnica mantiene el elemento "vivo" para las tecnologías de asistencia.

Cada vez que el usuario navega a un nuevo grupo de productos, actualizamos el contenido de esta región con JavaScript:

const liveRegion = document.getElementById("carousel-live");

const updateCarousel = () => {
  // ... código de actualización del carrusel ...

  // Anunciamos el cambio a los lectores de pantalla
  liveRegion.textContent = `Mostrando productos ${startVisible + 1} a ${endVisible} de ${totalItems}`;
};

Lenguaje del código:JavaScript

Cuando JavaScript modifica el textContent de un elemento con aria-live, el lector de pantalla detecta el cambio y lo anuncia. En VoiceOver, por ejemplo, el usuario escucharía: "Mostrando productos 4 a 6 de 6".

Podrías pensar: "¿Por qué no pongo aria-live directamente en el contenedor de productos?". El problema es que si haces eso, cada vez que cambie cualquier cosa dentro del track, el lector de pantalla intentaría anunciar todo el contenido, incluyendo todos los productos, precios, enlaces... Con una región live separada y oculta, controlamos exactamente qué mensaje queremos que el usuario escuche.

Ejemplo: Carrusel con rotación automática

Este es el caso más problemático. Los slides cambian solos cada pocos segundos, generalmente para mostrar promociones o banners. Si decides implementar uno (aunque mi recomendación es evitarlos cuando sea posible), vamos a ver como se puede hacer de la mejor manera.

Los carruseles con rotación automática son problemáticos por varias razones. En primer lugar, el usuario pierde el control al no poder decidir cuándo cambiar de contenido. Además, los usuarios con discapacidades cognitivas o motoras pueden no tener tiempo suficiente para procesar o interactuar con la información antes de que desaparezca. El movimiento constante también actúa como una distracción que dificulta la concentración en otras partes de la página. Por último, desde el punto de vista de la accesibilidad vestibular, este tipo de animaciones puede causar mareos en personas con trastornos vestibulares.

Si implementas rotación automática, obligatoriamente debes:

  • Proporcionar un botón de pausa/reaundar visible.
  • Pausar al detectar hover sobre el carrusel.
  • Pausar al detectar foco dentro del carrusel.
  • Respetar las preferencias del usuario
  • Usar intervalos largos (mínimo 5-7 segundos).

Atributos ARIA específicos para rotación automática

Además de los atributos que ya hemos visto, los carruseles con autoplay necesitan algunos específicos:

  • aria-pressed="true/false": en el botón de pausa, indica si la rotación está pausada (true) o activa (false). Los lectores de pantalla anunciarán "presionado" o "no presionado".
  • aria-live="off" cuando está rotando. Si el carrusel está en movimiento automático, deberías desactivar los anuncios para no bombardear al usuario con cambios que él no ha solicitado. Solo debes anunciar cuando el usuario interactúa manualmente.
  • Respetar prefers-reduced-motion: esta media-query CSS detecta si el usuario ha configurado en su sistema operativo que prefiere reducir las animaciones.
<!-- Botón de pausa accesible -->
<button 
  type="button"
  aria-label="Pausar rotación automática"
  aria-pressed="false"
  class="pause-btn"
>
  <span aria-hidden="true">⏸</span>
</button>

Lenguaje del código:HTML

// Pausar en hover y focus
carousel.addEventListener("mouseenter", pauseAutoplay);
carousel.addEventListener("mouseleave", resumeAutoplay);
carousel.addEventListener("focusin", pauseAutoplay);
carousel.addEventListener("focusout", resumeAutoplay);

// Respetar prefers-reduced-motion
const prefersReducedMotion = window.matchMedia(
  "(prefers-reduced-motion: reduce)",
).matches;

if (prefersReducedMotion) {
  disableAutoplay();
}

Lenguaje del código:JavaScript

/* Respetar preferencias del usuario */
@media (prefers-reduced-motion: reduce) {
  .carousel .slide {
    transition: none;
  }
}

Lenguaje del código:CSS

Vemos ahora el ejemplo interactivo accesible:

Este carrusel de productos rota automáticamente cada 5 segundos, pero pausa cuando pasas el cursor por encima o cuando el foco entra en el componente. El botón de pausa es visible y funcional. Y si tienes configurado prefers-reduced-motion: reduce en tu sistema, el carrusel no rotará automáticamente. Observa cómo usa el atributo inert para los productos ocultos, igual que el ejemplo anterior.

Una pregunta recurrente que me suelo encontrar, sobre todo entre diseñadores o desarrolladores que se acaban de iniciar en el mundo de la accesibilidad, es si el botón de pausa tiene que ser visible o si se puede poner invisible para que solo se active mediante navegación por teclado o lector de pantalla. La respuesta es clara: tiene que ser visible y accesible. Esto significa que debe cumplir con los requisitos de tamaño mínimo, contraste, alcanzabilidad, operabilidad y demás criterios de accesibilidad.

Otra pregunta frecuente sobre este tipo de botones es si es necesario incluir un botón de pausa en cada carrusel o si se puede implementar uno global. En este caso, sí se podría utilizar un botón global que pause y reanude todo el contenido de la página, siempre y cuando cumpla con los requisitos de accesibilidad: tamaño adecuado, contraste suficiente, fácil alcance y operabilidad correcta. Sin embargo, esta solución podría estar un poco "cogida con pinzas" según el caso, ya que dependerá del contexto y de cómo esté estructurado el contenido de la página.

Resumen de atributos ARIA para carruseles

A lo largo de los ejemplos hemos ido explicando los diferentes atributos ARIA. Aquí tienes un resumen rápido para tenerlos todos a mano:

AtributoDónde se usaQué hace
aria-role description="carrusel"Contenedor principalPersonaliza el anuncio del lector (dice "carrusel" en vez de "región")
aria-role description="slide"Cada slideEl lector anuncia "slide" en vez de "grupo"
aria-labelContenedor y controlesDa contexto ("Productos destacados", "Slide anterior")
role="group"Cada slideAgrupa el contenido del slide semánticamente
role="tablist"Indicadores de páginaImplementa el patrón de pestañas para los dots
aria-selectedIndicadoresComunica qué página/slide está activo
aria-hidden="true"Slides ocultosOculta el contenido de lectores de pantalla
aria-live="polite"Región de anunciosAnuncia cambios cuando el usuario interactúa
aria-pressedBotón de pausaIndica si la rotación está pausada o activa
inertElementos no visiblesDesactiva completamente la interacción
tabindexElementos interactivosControla qué elementos reciben foco con Tab

Comportamiento de teclado

Un carrusel accesible debe soportar navegación completa por teclado. Pero ojo, no es tan simple como "añadir soporte para Tab". La forma en que implementamos la navegación por teclado afecta directamente a la experiencia del usuario.

El patrón de navegación recomendado

TeclaAcción
TabMueve el foco al carrusel (no a través de él). El primer Tab llega al primer control interactivo (normalmente el botón de anterior). Siguiente Tab pasa al contenido del slide visible. Siguiente Tab sale del carrusel.
Shift + TabNavegación inversa, saliendo del carrusel hacia el elemento anterior de la página.
Enter o EspacioActiva el control enfocado (botones de navegación, enlaces dentro de slides, botón de pausa).
Flecha izquierdaEn los indicadores de página (dots), va al slide anterior.
Flecha derechaEn los indicadores de página (dots), va al siguiente slide.
HomeEn los indicadores, va al primer slide.
EndEn los indicadores, va al último slide.
EscapeSi hay un modal o tooltip abierto dentro del carrusel, lo cierra. En carruseles con rotación automática, puede usarse para pausar.

Alternativas a los carruseles

Antes de implementar un carrusel, pregúntate: ¿realmente necesito un carrusel? Como dice shouldiuseacarousel.com: "Probablemente no".

Algunas alternativas más accesibles:

  • Grid de tarjetas: Muestra todo el contenido a la vez. Sin elementos ocultos, sin estados complejos, navegación natural con Tab.
  • Acordeón con <details>: El usuario controla qué contenido ver. Funciona sin JavaScript y tiene soporte nativo del navegador.
  • Pestañas (Tabs): Para contenido mutuamente excluyente. El usuario ve claramente cuántas secciones hay.
  • Hero estático: En lugar de rotar 5 promociones que nadie ve, elige la más importante y dale protagonismo.

Si después de considerar las alternativas decides que sí necesitas un carrusel, ahora sabes cómo hacerlo más accesible.

Librerías y sistemas de diseño con carruseles accesibles

Existen algunas opciones si quieres librerías que te faciliten la vida haciendo carruseles. A veces, no hace falta reinventar la rueda:

  • Splide: Una de las mejores opciones. Ligera (29KB min), sin dependencias, y con excelente soporte de accesibilidad por defecto. Incluye navegación por teclado, ARIA labels, live regions, y soporte para prefers-reduced-motion. Tiene documentación específica sobre accesibilidad.
  • Embla Carousel: Librería modular y muy ligera (solo 3KB gzipped). No incluye accesibilidad por defecto, pero ofrece guías detalladas sobre cómo implementarla. Ideal si quieres control total.
  • Swiper: La más completa y popular. Incluye un módulo de accesibilidad (a11y) que añade ARIA labels, navegación por teclado, y anuncios de live regions automáticamente. Solo hay que activarlo en la configuración.
  • Glide.js : Otra opción ligera (~28KB) con soporte básico de accesibilidad. Requiere configuración manual de ARIA attributes pero incluye navegación por teclado.

Patrones de referencia

Antes de elegir una librería, es importante también comprender entender el patrón correcto:

  • WAI-ARIA Authoring Practices - Carousel: La guía oficial del W3C con el patrón de diseño recomendado para carruseles accesibles. Es la referencia definitiva. Incluye ejemplos de código funcionales que puedes estudiar.
  • Deque University - Accessible Carousels: Ejemplos prácticos y código de referencia de los expertos en accesibilidad de Deque. Muy útil para entender los errores comunes y cómo evitarlos.
  • Inclusive Components - A Content Slider: Artículo de Heydon Pickering (autor del libro "Inclusive Components") con un enfoque práctico y detallado sobre cómo construir un carrusel accesible desde cero.

Conclusión

¿Recuerdas ese banner con la oferta increíble que desaparecía antes de poder hacer clic? Esa sensación de estar corriendo detrás de un tren en marcha es exactamente lo que experimentan millones de usuarios cada día. Pero ahora ya sabes cómo evitarlo.

A lo largo de este artículo, hemos visto que los carruseles son componentes complejos desde el punto de vista de la accesibilidad, pero no imposibles de hacer bien. Lo importante es en entender que un carrusel tiene que ser accesible para todos.

Hemos explorado dos tipos de carruseles con diferentes niveles de complejidad: carruseles de productos con múltiples elementos visibles y carruseles con rotación automática.

En cada caso, la diferencia entre una implementación inaccesible y una accesible está en los detalles: roles ARIA correctos, gestión del foco con inert para evitar que los usuarios tengan que recorrer todos los elementos, navegación por teclado bien pensada, y respeto por las preferencias del usuario como prefers-reduced-motion.

Si quieres profundizar en la implementación de componentes accesibles, te invitamos a nuestros talleres prácticos de accesibilidad, donde trabajamos con ejemplos reales y aprendemos a auditar y corregir problemas de accesibilidad.

Referencias

Escrito por:

Únete a nuestra comunidad para aprender y estar al día sobre accesibilidad digital.

Recibirás recursos y artículos semanalmente para que puedas aprender, compartir y ser parte de la comunidad de accesibilidad digital.
¿Quieres colaborar en nuestra Newsletter? Escríbenos a hola@weaaare.com