Addaw, ir a inicio Donar

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

Tablas de datos accesibles

Una tabla de datos es una relación bidimensional: cada celda tiene sentido por su fila y su columna. Quien ve la pantalla hace esa asociación de un vistazo. Quien usa un lector de pantalla depende de que el marcado la declare, porque el lector lee celda a celda y, al entrar en cada una, anuncia los encabezados que le corresponden. Si los encabezados no están bien marcados, la persona oye «1.250,00» sin saber si es el importe de enero o de febrero, o si corresponde a ingresos o a gastos. Todo esto cae bajo el criterio 1.3.1 Información y relaciones.

Anatomía de una tabla accesible

Una tabla de datos bien construida tiene estos elementos:

  • <caption>: el título de la tabla. Es su nombre accesible, lo primero que anuncia el lector al entrar y lo que aparece en la lista de tablas. Debe ser el primer hijo de <table>.
  • <thead>, <tbody> y, si procede, <tfoot>: agrupan filas. No son obligatorios para la accesibilidad, pero ayudan y permiten cabeceras fijas con CSS.
  • <th> para cada celda de encabezado, con scope="col" si encabeza una columna o scope="row" si encabeza una fila.
  • <td> para las celdas de datos.

Ejemplo

<table>
  <caption>Tasas municipales 2025 por tipo de trámite</caption>
  <thead>
    <tr>
      <th scope="col">Trámite</th>
      <th scope="col">Tasa ordinaria</th>
      <th scope="col">Tasa reducida</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th scope="row">Licencia de obra menor</th>
      <td>45,00 €</td>
      <td>22,50 €</td>
    </tr>
    <tr>
      <th scope="row">Vado permanente</th>
      <td>120,00 €</td>
      <td>60,00 €</td>
    </tr>
  </tbody>
</table>

Al llegar a «22,50 €», NVDA anuncia algo como «Tasa reducida, Licencia de obra menor, 22,50 €»: la persona sabe exactamente qué dato está leyendo.

Las celdas de encabezado de fila son las que más se olvidan. Si la primera columna contiene <td> en lugar de <th scope="row">, el lector solo anunciará el encabezado de columna y la persona tendrá que volver atrás constantemente para recordar en qué fila está.

Tablas complejas: headers e id

Cuando una tabla tiene encabezados en dos niveles (por ejemplo, años agrupados por trimestres) o celdas que ocupan varias filas o columnas con colspan y rowspan, scope (incluidos sus valores colgroup y rowgroup) puede no bastar, o no ser interpretado de forma fiable por todos los lectores, para describir qué encabezados corresponden a cada celda. En ese caso se asigna un id a cada <th> y cada <td> enumera en headers los identificadores de sus encabezados, separados por espacios.

<table>
  <caption>Usuarios atendidos por canal y semestre</caption>
  <tr>
    <td rowspan="2"></td>
    <th id="a24" colspan="2">2024</th>
  </tr>
  <tr>
    <th id="s1" headers="a24">1.º semestre</th>
    <th id="s2" headers="a24">2.º semestre</th>
  </tr>
  <tr>
    <th id="pres" scope="row">Presencial</th>
    <td headers="a24 s1 pres">8.120</td>
    <td headers="a24 s2 pres">7.950</td>
  </tr>
</table>

Es laborioso y propenso a errores, así que antes de llegar aquí pregúntate si la tabla puede dividirse en varias tablas simples, una por grupo. Casi siempre es mejor para todo el mundo, incluidas las personas que la leen en un móvil.

Punto clave

Si puedes explicar cada celda con un encabezado de fila y uno de columna, usa scope. Si necesitas más de dos encabezados por celda, o la tabla es irregular, divide la tabla o usa headers/id. Nunca dejes encabezados en <td> con negrita.

Tablas de maquetación

Usar tablas para colocar elementos en pantalla fue la norma hace veinte años y sigue siendo habitual en plantillas de correo HTML. Para una tecnología de apoyo, una tabla de maquetación es un laberinto: anuncia «tabla con 3 filas y 4 columnas», lee coordenadas de celdas y genera un orden de lectura ilógico. En páginas web, maqueta con CSS (Grid, Flexbox). Si heredas una tabla de maquetación que no puedes rehacer, añade role="presentation" al elemento <table> para que el navegador la retire del árbol de accesibilidad como tabla, y no utilices en ella <th>, <caption> ni summary.

Error frecuente

El atributo summary está obsoleto en HTML y no debe usarse. Si una tabla necesita una explicación sobre cómo está organizada, ponla en un párrafo antes de la tabla o dentro de <caption>. Otro error: poner el título de la tabla en un <h3> justo encima y dejar la tabla sin <caption>. Si por diseño el título debe ser un encabezado, puedes vincularlo con aria-labelledby en la <table>, pero <caption> es la solución nativa y preferible.

Tablas en pantallas pequeñas

En móvil las tablas anchas suelen romper el criterio 1.4.10 Reajuste de los elementos, que exige evitar el desplazamiento horizontal salvo en contenido que lo requiera por naturaleza. Las tablas de datos son una de las excepciones admitidas, pero aun así conviene ofrecer una solución amable. La más segura es envolver la tabla en un contenedor con desplazamiento horizontal propio:

<div class="tabla-scroll" role="region" aria-labelledby="cap-tasas" tabindex="0">
  <table>
    <caption id="cap-tasas">Tasas municipales 2025</caption>
    …
  </table>
</div>

El tabindex="0" permite desplazar el contenedor con las flechas del teclado y el role="region" con nombre evita el fallo de «elemento enfocable sin rol ni nombre». Las técnicas que transforman cada fila en una tarjeta con CSS (display: block en tr y td) rompen la semántica de tabla en muchos navegadores; si las usas, verifica con lector de pantalla en móvil y considera añadir los roles de tabla explícitos (role="table", role="row", role="cell", role="columnheader") para restaurarla.

Pruébalo tú

Copia la tabla de tasas del primer ejemplo en un archivo HTML de tu ordenador y ábrela en el navegador. Recórrela con NVDA usando Ctrl+Alt+flechas y escucha qué se anuncia al llegar a «22,50 €». Después cambia los <th scope="row"> por <td> y repite: notarás enseguida qué información se pierde y por qué los encabezados de fila importan.

Cómo comprobarlo

  • Con el lector de pantalla, entra en la tabla y muévete entre celdas con Ctrl+Alt+flechas (NVDA y JAWS). Debe anunciar el encabezado correcto al cambiar de fila y de columna.
  • Con WAVE o axe, revisa los avisos de «celda de datos sin encabezado» y «encabezado sin celdas asociadas».
  • Inspecciona la <caption>: ¿describe lo que contiene la tabla, incluida la unidad o el periodo?
  • Redimensiona a 320 píxeles de ancho y comprueba que la tabla puede desplazarse con teclado.

Resumen

  • Toda tabla de datos necesita <th> para cada encabezado, con scope de columna o de fila, y conviene que tenga un <caption> que le dé nombre.
  • Los encabezados de fila (scope="row") son los que más se olvidan y los que más ayudan a orientarse.
  • Para tablas con encabezados en varios niveles, usa id y headers, o mejor, divide la tabla.
  • No maquetes con tablas; si heredas una, role="presentation" y sin <th>.
  • En móvil, un contenedor con desplazamiento, nombre y tabindex="0" es la solución más robusta.

Comprueba lo que has aprendido

Esta lección se puede leer libremente. Para hacer su test de 3 preguntas, los ejercicios prácticos con páginas reales, guardar tu avance y optar al examen y al certificado, matricúlate en el curso.