Addaw, ir a inicio Donar

Lección 8 de 10 · 17 min de lectura · Revisado el 26/10/2026

Carruseles, tablas interactivas y arrastrar y soltar (2.5.7)

Estás leyendo una lección abierta. Matricúlate gratis para hacer los tests y ejercicios, guardar tu avance y conseguir el certificado.

Esta lección reúne tres componentes que combinan movimiento, densidad de información y gestos: los carruseles de la portada, las tablas con ordenación y filtros, y las interfaces de arrastrar y soltar. Son los que más criterios distintos tocan a la vez: tiempo y movimiento (2.2.2 Poner en pausa, detener, ocultar), teclado (2.1.1), nombre y estado (4.1.2), gestos (2.5.1 Gestos del puntero, 2.5.7 Movimientos de arrastre) y tamaño del objetivo (2.5.8).

Carruseles

Los carruseles automáticos son uno de los componentes peor valorados en los estudios de usabilidad y una fuente constante de incumplimientos. Si el equipo de diseño insiste, el patrón Carousel de la APG (se abre en una ventana nueva) marca el mínimo:

  • Contenedor con role="region" (o <section>), aria-roledescription="carrusel" y un nombre con aria-label («Noticias destacadas»).
  • Control de pausa como primer elemento enfocable, con aria-pressed o texto alternante («Pausar la rotación» / «Reanudar la rotación»). Es obligatorio por 2.2.2 si el movimiento dura más de 5 segundos y es automático. Además, la rotación debe detenerse mientras el puntero o el foco estén dentro del carrusel.
  • Botones anterior y siguiente con nombre («Diapositiva anterior», «Diapositiva siguiente»), de al menos 24 por 24 píxeles CSS.
  • Cada diapositiva en un contenedor con role="group", aria-roledescription="diapositiva" y nombre («2 de 5» o el título de la noticia).
  • Indicadores de posición (los puntos) como botones con nombre («Ir a la diapositiva 3») o como pestañas si siguen el patrón tablist.
  • Diapositivas no visibles ocultas al árbol (aria-hidden="true" o hidden) y sin elementos enfocables, para que Tab no recorra enlaces invisibles.
  • Anuncio de cambios: si la persona pulsa «siguiente», la región de diapositivas puede llevar aria-live="polite" mientras la rotación automática esté parada, y aria-live="off" mientras gire sola, para no interrumpir cada pocos segundos.

Ejemplo

<section aria-roledescription="carrusel" aria-label="Noticias destacadas">
  <button type="button" aria-pressed="false">Pausar la rotación</button>
  <button type="button">Diapositiva anterior</button>
  <button type="button">Diapositiva siguiente</button>
  <div aria-live="off">
    <div role="group" aria-roledescription="diapositiva" aria-label="1 de 3">…</div>
    <div role="group" aria-roledescription="diapositiva" aria-label="2 de 3" hidden>…</div>
    <div role="group" aria-roledescription="diapositiva" aria-label="3 de 3" hidden>…</div>
  </div>
</section>

Y respeta prefers-reduced-motion: si la persona ha pedido menos movimiento en su sistema, el carrusel no debe girar solo (lo veremos en el curso de CSS).

La alternativa más accesible, y a menudo más eficaz, es no rotar: una rejilla estática con las tres noticias.

Tablas interactivas

Sobre la base de la tabla de datos accesible del primer curso, las tablas con ordenación, filtros y acciones por fila añaden requisitos:

  • Ordenación: el control de ordenar debe ser un <button> dentro del <th>, con nombre («Ordenar por fecha») y, en el <th>, aria-sort="ascending|descending|none" actualizado. Al reordenar, anuncia el resultado en una región de estado («Ordenado por fecha, de más reciente a más antigua»).
  • Acciones por fila: cada botón necesita un nombre que identifique la fila («Editar el expediente 2024/0123»), porque fuera de contexto «Editar» repetido veinte veces no sirve. Puede hacerse con texto oculto accesiblemente o con aria-labelledby combinando el texto del botón y la celda identificadora.
  • Selección de filas: casillas de verificación nativas con etiqueta («Seleccionar el expediente 2024/0123») y una casilla de cabecera «Seleccionar todo» que refleje el estado mixto con indeterminate.
  • Paginación y filtros: anuncia en una región de estado el número de resultados tras cada cambio; la paginación es una <nav aria-label="Paginación"> con enlaces o botones y aria-current="page" en la página actual.
  • Rejillas editables (hoja de cálculo): solo entonces el rol grid de la APG, con navegación por celdas con flechas y una sola parada de Tab. Para una tabla que se lee, aunque tenga botones, <table> normal es lo correcto. Verás el patrón grid a fondo en la lección siguiente.

Error frecuente

Hacer clicable toda la fila (<tr onclick>) para abrir el detalle, sin ningún enlace ni botón dentro. No es alcanzable con teclado ni tiene rol ni nombre. Pon un enlace real en la celda principal (el identificador o el título) y, si quieres, amplía su área clicable con CSS; la fila entera como objetivo es un extra para el ratón, nunca el único camino.

Arrastrar y soltar y 2.5.7

WCAG 2.2 añadió el criterio 2.5.7 Movimientos de arrastre (AA): toda funcionalidad que use un movimiento de arrastre debe poder realizarse con un único puntero sin arrastrar (es decir, con clics o toques), salvo que el arrastre sea esencial o lo determine el agente de usuario. Afecta a reordenar listas, mover tarjetas entre columnas (tableros kanban), deslizadores, recortar imágenes, ordenar prioridades y mover elementos en un mapa.

Fíjate en que 2.5.7 habla de puntero, no de teclado: la alternativa de teclado es exigible por 2.1.1, pero además hace falta una alternativa de puntero sin arrastre, porque muchas personas con temblor, poca fuerza o que usan un lápiz o un ratón de cabeza pueden hacer clic pero no mantener pulsado mientras mueven con precisión.

Ejemplo

Lista de prioridades reordenable. Además del arrastre, cada elemento ofrece botones de mover:

<ul aria-label="Orden de prioridad">
  <li>
    Renovar el DNI
    <button type="button" aria-label="Subir Renovar el DNI">↑</button>
    <button type="button" aria-label="Bajar Renovar el DNI">↓</button>
  </li>
  …
</ul>
<p role="status"></p>

Tras cada movimiento se anuncia «Renovar el DNI movido a la posición 2 de 4» en la región de estado y el foco permanece en el botón pulsado (que ahora está en la nueva posición; si el script mueve el elemento en el DOM, vuelve a llamar a focus() sobre el botón, porque el navegador puede perderlo). Otras alternativas conformes: un menú «Mover a…» con destinos, un campo numérico de posición, o seleccionar el elemento y después pulsar el destino (dos clics).

Para los deslizadores, el <input type="range"> nativo cumple de serie: admite clic en cualquier punto de la pista y flechas con teclado. Las excepciones de 2.5.7 son estrechas: dibujar a mano alzada es esencial; reordenar una lista, no.

Punto clave

Carrusel: pausa, botones con nombre, diapositivas ocultas al árbol y sin rotación si la persona prefiere menos movimiento. Tabla interactiva: botones de ordenar con aria-sort, nombres de acción que identifican la fila, anuncios de estado. Arrastre: siempre una alternativa de clics o botones (2.5.7) y de teclado (2.1.1).

Cómo comprobarlo

  • Carga la página y espera: si algo se mueve más de 5 segundos sin control de pausa accesible con teclado, falla 2.2.2.
  • Tabula por el carrusel: no deben aparecer paradas en diapositivas invisibles.
  • En la tabla, ordena con teclado y escucha el anuncio; abre la lista de botones del lector y verifica que cada acción identifica su fila.
  • Intenta cada operación de arrastre solo con clics y solo con teclado; si alguna es imposible, falla 2.5.7 o 2.1.1.
  • Mide los botones pequeños de los carruseles y las tablas: 24 por 24 píxeles CSS o separación equivalente (2.5.8).

Resumen

  • Un carrusel automático necesita control de pausa (2.2.2), botones con nombre, diapositivas ocultas al árbol y respeto a prefers-reduced-motion; la rejilla estática suele ser mejor.
  • En tablas interactivas, los botones de ordenar llevan aria-sort, las acciones de fila identifican la fila y los cambios se anuncian con role="status".
  • Una fila clicable sin enlace ni botón dentro es inaccesible; el enlace real va en la celda principal.
  • 2.5.7 exige una alternativa de puntero sin arrastre (clics, botones, menú «Mover a») para toda función de arrastrar y soltar no esencial, además del teclado.
  • Los objetivos de estos componentes deben medir al menos 24 por 24 píxeles CSS (2.5.8).

Llevas 5 lecciones de este curso: que no se pierdan

Crea tu cuenta gratis y guarda lo que ya has leído y sigue el curso con todo:

  • El test de esta lección (3 preguntas) para comprobar lo que has aprendido
  • Ejercicios prácticos con páginas reales
  • Tu avance guardado: sigues donde lo dejaste, desde cualquier dispositivo
  • Constancia del curso con sus horas y certificado gratuito del nivel 3 al aprobar el examen

Entras con tu cuenta de Google o solo con tu email. No hace falta contraseña.