Skip to content
This page has been auto-translated and may contain errors.View in English

Tablas ​

docs.scrimba.com

Cierta información tiene forma de cuadrícula. Un horario de trenes, un plan de precios, una tabla de posiciones, una lista de datos nutricionales: cada una tiene filas y columnas, y el significado está en cómo se alinean. HTML tiene un conjunto de elementos dedicados exactamente a este tipo de contenido, y usarlos mantiene la cuadrícula legible tanto en pantalla como para el software que lee la página en voz alta.

Lo básico de las tablas ​

Una tabla es una cuadrícula de filas y columnas, con la misma forma que una hoja de cálculo. Se construye con cuatro elementos. <table> envuelve toda la cuadrícula. Cada <tr> es una fila (tr viene de table row). Dentro de una fila, cada <td> es una celda de datos (td es table data). Cuando una celda etiqueta su columna o fila, usas <th> en su lugar (th es table header), y el navegador la muestra en negrita y centrada para que se distinga de los datos.

Una tabla se construye fila por fila, nunca columna por columna. <table> es el contenedor, cada <tr> es una fila, y las celdas se ubican dentro de la fila en el orden en que aparecen a lo largo de la página. Una celda de datos es <td>; una celda de encabezado es <th>. No existe un elemento para columnas. Las columnas surgen de que cada fila mantenga sus celdas en el mismo orden, así que si una fila se desalinea, la cuadrícula deja de coincidir.

La diferencia entre <th> y <td> no es solo estética. <th> marca una celda como encabezado de la fila o columna en la que está. El estilo predeterminado del navegador, en negrita y centrado, es solo la mitad visible de eso. La otra mitad es un significado que otro software puede leer.

El origen de una tabla es por filas: la escribes una fila a la vez, y la columna de cada celda se decide únicamente por su posición dentro de la fila. El navegador lee ese código fila por fila y construye a partir de él una cuadrícula bidimensional, emparejando celdas en columnas según su posición contando de izquierda a derecha. Nada en el marcado nombra una columna, así que la cuadrícula solo queda tan alineada como consistentes sean tus filas.

<th> frente a <td> es una distinción semántica, no de estilo. <th> (una celda de encabezado) le indica al navegador, y a cualquier tecnología de asistencia que lea la página (software como un lector de pantalla, que lee la página en voz alta para quienes no pueden verla), que esa celda es una etiqueta para los datos que la rodean. El aspecto predeterminado en negrita y centrado es incidental: quítalo con CSS y el encabezado sigue significando "encabezado", porque el significado vive en el elemento, no en su apariencia. Esa es la razón de fondo para usar una tabla real en vez de dibujar una cuadrícula de otra manera.

html
<table>
  <tr>
    <th>Día</th>
    <th>Horario de apertura</th>
  </tr>
  <tr>
    <td>Lunes</td>
    <td>8:00 a 18:00</td>
  </tr>
  <tr>
    <td>Sábado</td>
    <td>9:00 a 14:00</td>
  </tr>
</table>

Dos celdas de encabezado arriba, luego dos filas de datos. El navegador dibuja la cuadrícula, ajusta el tamaño de cada columna a su contenido y muestra las dos celdas <th> en negrita.

JunoLo básico de las tablas Cuatro elementos forman una cuadrícula: <table> alrededor de todo, <tr> para cada fila, <td> para una celda, y <th> para una celda de encabezado. Las celdas de encabezado salen en negrita y centradas para distinguirse de los datos. Constrúyela fila por fila y las columnas se alinean solas.
JunoLo básico de las tablas Armas una tabla fila por fila con <tr>, y las columnas surgen de que cada fila mantenga sus celdas en el mismo orden. <th> para encabezados, <td> para datos, y esa elección tiene significado, no solo el aspecto en negrita. Si te equivocas con la cantidad de celdas en una fila, toda la cuadrícula queda torcida.
JunoLo básico de las tablas El marcado se organiza por filas, así que una columna solo existe porque cada fila mantiene sus celdas en el mismo orden. Cuenta con cuidado. <th> se gana su lugar al decirle a un lector de pantalla que la celda es una etiqueta, algo que ninguna cantidad de negrita con CSS puede lograr. Esa distinción semántica es la razón de fondo para usar una tabla real.

Estructurar una tabla ​

El orden de tus filas es el orden en que la gente las lee, así que coloca la fila de encabezado, la formada por celdas <th>, en la parte superior. Luego mantén todas las filas con la misma longitud: si la fila de encabezado tiene tres celdas, cada <tr> debajo también necesita tres celdas <td>. Una fila con una celda faltante deja un hueco en la cuadrícula y las columnas dejan de coincidir. Aquí no hay nada nuevo que aprender, solo hay que tener cuidado con las filas que ya conoces.

Cuando una tabla crece, agrupa sus filas en grupos de filas para que la estructura quede explícita. Envuelve la fila de encabezado en <thead>, las filas de datos en <tbody>, y cualquier fila de resumen como una línea de totales en <tfoot>. Estos grupos no cambian mucho la disposición visual por sí solos, pero etiquetan las partes de la tabla para el estilo, para la impresión y para el software de asistencia.

Ponle un título a la tabla con <caption>, colocado como el primer elemento hijo de <table>. Se muestra arriba de la cuadrícula y, a diferencia de un encabezado que pones al lado de la tabla, este queda vinculado a la tabla en el marcado.

Cuando una celda necesita abarcar más de una columna o fila, usa colspan o rowspan. colspan="2" hace que una celda ocupe el ancho de dos columnas; rowspan="2" hace que ocupe el alto de dos filas. Las posiciones que cubre quedan entonces excluidas de esas filas, porque ese espacio ya está ocupado:

html
<thead>
  <tr>
    <th rowspan="2">Región</th>
    <th colspan="2">2024</th>
  </tr>
  <tr>
    <th>T1</th>
    <th>T2</th>
  </tr>
</thead>

"Región" llena dos filas de encabezado, "2024" llena dos columnas, y T1 y T2 se ubican debajo en la segunda fila.

Los grupos de filas no son decoración. <thead> y <tfoot> están definidos para repetirse en cada página cuando se imprime una tabla larga, de modo que un encabezado se mantenga visible después de un salto de página, y te permiten mantener un encabezado o pie fijo mientras <tbody> se desplaza. Una tabla puede contener varios grupos <tbody>, lo cual es una forma limpia de dividir un conjunto de datos largo en secciones etiquetadas sin romper la cuadrícula única.

colspan y rowspan controlan la expansión de celdas (una celda que cubre más de una columna o fila), y aquí es donde las tablas más a menudo se rompen sin avisar. Cada fila igual debe cubrir el ancho completo de la cuadrícula. Una celda con colspan="2" llena dos columnas, así que las filas que se superponen con ella deben dejar esas posiciones vacías en lugar de aportar su propia celda. Si te equivocas en el conteo, el navegador de todas formas mostrará algo, pero no la cuadrícula que querías. <caption> es el nombre accesible de la tabla: el software de asistencia (herramientas como los lectores de pantalla que leen la página en voz alta) lo anuncia cuando el lector llega a la tabla, cumpliendo una función que un encabezado cercano no puede cumplir.

html
<table>
  <caption>Ingresos trimestrales por región</caption>
  <thead>
    <tr>
      <th>Región</th>
      <th>T1</th>
      <th>T2</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>Norte</th>
      <td>$12.000</td>
      <td>$15.400</td>
    </tr>
    <tr>
      <th>Sur</th>
      <td>$9.800</td>
      <td>$11.200</td>
    </tr>
  </tbody>
  <tfoot>
    <tr>
      <th>Total</th>
      <td>$21.800</td>
      <td>$26.600</td>
    </tr>
  </tfoot>
</table>
JunoEstructurar una tabla Las filas se leen de arriba hacia abajo, así que empieza con tu fila de encabezado de celdas <th>. Luego mantén todas las filas con la misma longitud: tres encabezados arriba significa tres celdas <td> en cada fila debajo. Una celda faltante es un hueco en la cuadrícula, y eso es lo que suele confundir al principio.
JunoEstructurar una tabla Agrupa las partes cuando una tabla crece: <thead> para la fila de encabezado, <tbody> para los datos, <tfoot> para una línea de totales, y un <caption> como primer hijo para el título. colspan y rowspan extienden una celda a lo largo de columnas o filas, pero recuerda que las posiciones cubiertas se excluyen de esas filas. Si los conteos son correctos, la cuadrícula se sostiene.
JunoEstructurar una tabla Los grupos cumplen una función real: <thead> y <tfoot> se repiten cuando la tabla se imprime y pueden anclar un cuerpo que se desplaza, y <caption> es el nombre que un lector de pantalla lee en voz alta. La expansión es la trampa silenciosa, ya que cada fila igual tiene que llenar el ancho completo de la cuadrícula, así que una posición cubierta no recibe celda propia. El navegador muestra un error de conteo sin quejarse, y por eso es tan difícil detectarlo.

Tablas accesibles ​

Una tabla accesible es aquella que tiene sentido para todos, incluidas las personas que escuchan la página con un lector de pantalla (software que lee la página en voz alta) en lugar de verla. Lo más útil que puedes hacer ya está en tus herramientas: usa <th> para cada celda de encabezado, no <td>. Así, un lector de pantalla puede decirle a quien escucha cuáles celdas son etiquetas y cuáles son datos, de modo que un valor como "$15" se anuncia junto con la columna a la que pertenece. Una tabla donde cada celda es un simple <td> se escucha como una pared plana de números sin nada que los sostenga.

<th> marca una celda como encabezado, pero en una tabla con encabezados de columna y de fila a la vez no indica cuál es cuál. El atributo scope lo hace explícito. scope="col" indica que un encabezado etiqueta toda su columna; scope="row" indica que etiqueta toda su fila. Agrégalo a cada <th> y un lector de pantalla podrá relacionar cualquier celda de datos con el encabezado de columna y el de fila correctos al mismo tiempo.

html
<th scope="col">Mes</th>
<th scope="row">Lluvia</th>

En una cuadrícula simple, el navegador a menudo puede adivinar estas asociaciones, pero declararlas con scope elimina las conjeturas y es fácil de agregar.

scope cubre tablas con un solo nivel de encabezados de fila y columna. Las tablas complejas, con un encabezado que abarca varias columnas o dos niveles de encabezados de columna, siguen siendo ambiguas incluso con scope, porque una celda de datos ya no tiene exactamente un encabezado de columna y uno de fila por encima de ella. Para esos casos, asocia las celdas explícitamente con id y headers. Dale a cada celda de encabezado un id (un nombre único para ese elemento), y luego enumera los ids relevantes en el atributo headers de cada celda de datos:

html
<th id="t1">T1</th>
<th id="norte">Norte</th>
<td headers="norte t1">$12.000</td>

Ahora la celda de datos indica exactamente qué encabezados la describen, en el orden en que deben leerse, y ningún algoritmo tiene que inferir la relación. Es verboso, así que resérvalo para las tablas que realmente lo necesitan. Recurre primero a scope y solo escala a id y headers cuando la estructura de encabezados sea demasiado irregular como para que scope la exprese.

La accesibilidad va mucho más allá de las tablas; el capítulo de Accesibilidad cubre el resto del panorama.

JunoTablas accesibles El mayor beneficio no cuesta nada extra: usa <th> para los encabezados y <td> para los datos. Un lector de pantalla se apoya en esa distinción para leer cada valor junto con el encabezado al que pertenece, de modo que $15 llega acompañado de su columna en vez de estar suelto. Si te lo saltas, toda la tabla se percibe como una pared de números sueltos.
JunoTablas accesibles Pon scope en tus celdas de encabezado: scope="col" para un encabezado de columna, scope="row" para uno de fila. Eso permite que un lector de pantalla vincule cada celda de datos con el encabezado correcto en ambos ejes. El navegador puede adivinarlo en cuadrículas simples, pero declararlo es fácil y elimina las conjeturas.
JunoTablas accesiblesscope resuelve la cuadrícula común con un encabezado por eje. Cuando los encabezados se combinan o se apilan y una celda tiene más de uno en un eje, cambia a id en los encabezados y headers en las celdas de datos para conectarlos a mano. Es engorroso, así que resérvalo para las tablas que realmente lo necesitan y deja que scope se encargue del resto.

Para qué son las tablas ​

Hubo una época, antes de que CSS pudiera manejar la disposición visual, en que la gente construía diseños de página completos usando tablas: una <table> para poner el menú a la izquierda y el contenido a la derecha. Visualmente funciona, así que todavía se ve en páginas viejas y en algunas plantillas de correo. No lo copies. Una tabla es para datos tabulares, información que pertenece a una cuadrícula de filas y columnas. Organizar las piezas de una página es trabajo de CSS. Usar una tabla para posicionar cosas en vez de para contener datos hace la página más difícil de leer para cualquiera que use un lector de pantalla, y más difícil de ajustar después.

La regla es breve: una <table> significa "este contenido es una cuadrícula de datos relacionados". Úsala cuando la información realmente tenga filas y columnas: un horario, una comparación, un conjunto de resultados. No la uses para organizar una página, ni para alinear cosas que no son datos. CSS grid y flexbox manejan la disposición visual de forma adecuada, se adaptan al tamaño de la pantalla y mantienen tu HTML describiendo contenido en vez de describir una disposición.

Recurrir a una tabla para lograr columnas es el mal uso clásico. Si el contenido es una barra de navegación o un formulario distribuido por la página, no son datos tabulares, y una tabla es la herramienta equivocada aunque se pueda hacer que se vea bien.

Cuando usas una tabla para la disposición visual, le entregas al software de asistencia (herramientas como los lectores de pantalla que leen la página en voz alta) una estructura de datos que no es datos. Un lector de pantalla anuncia una tabla por sus dimensiones y permite que el usuario se mueva celda por celda, tratando el andamiaje visual como si cada región fuera un valor relacionado dentro de una cuadrícula. El resultado son anuncios como "tabla, cuatro columnas, diez filas" para algo que en realidad es un encabezado, una barra lateral y un artículo.

También hay un problema de orden de lectura. El software de asistencia y los motores de búsqueda leen la página en orden de origen, el orden en que los elementos aparecen en tu HTML, no el orden en que se ubican visualmente en pantalla. Una tabla usada para maquetar obliga a que tu orden de origen coincida con la cuadrícula visual, así que el contenido que debería aparecer primero para quien escucha, el artículo principal, puede terminar después de una columna de navegación solo porque ahí es donde la columna visual lo necesitaba. La disposición con CSS rompe ese acoplamiento: puedes mantener el contenido importante temprano en el código y de todas formas ubicarlo donde quieras en pantalla. Reserva las tablas para los datos, y el orden de lectura queda bajo tu control.

La única zona gris es el correo electrónico en HTML, donde algunos clientes de correo más antiguos todavía carecen de una disposición CSS confiable y la estructura basada en tablas sigue siendo común. Eso es una limitación propia de ese medio, no un patrón que debas traer de vuelta a la web.

html
<!-- Incorrecto: una tabla usada para ubicar una barra lateral junto a un artículo -->
<table>
  <tr>
    <td><nav>...</nav></td>
    <td><article>...</article></td>
  </tr>
</table>

<!-- Correcto: elementos reales, con CSS manejando las columnas -->
<nav>...</nav>
<article>...</article>

Esta es la misma separación entre estructura y presentación planteada en ¿Qué es HTML?: estructura en HTML, disposición visual en CSS. Para elegir elementos según su significado, consulta HTML semántico.

JunoPara qué son las tablas Una tabla es para datos que pertenecen a una cuadrícula, filas y columnas de valores relacionados. No es para organizar una página, aunque los sitios antiguos la usaran así. Posicionar las partes de una página es trabajo de CSS, y meter eso dentro de una tabla hace que la página sea más difícil de leer en voz alta y más difícil de cambiar.
JunoPara qué son las tablas Usa <table> solo cuando el contenido realmente sea una cuadrícula de datos: un horario, una comparación, una lista de resultados. Para organizar una página o alinear cosas que no son datos, recurre a CSS grid o flexbox, que se adaptan a la pantalla y mantienen tu HTML enfocado en el contenido. Una tabla forzada a hacer de maquetación es la herramienta equivocada por excelencia.
JunoPara qué son las tablas Una tabla usada para maquetar confunde a un lector de pantalla: escucha una cuadrícula de datos y anuncia filas y columnas que no significan nada. También fija tu orden de origen a la cuadrícula visual, cuando el orden de origen es justamente lo que las tecnologías de asistencia y los motores de búsqueda leen. Reserva las tablas para los datos, deja que CSS ubique las cosas, y el orden de lectura queda bajo tu control. El correo electrónico en HTML es la única excepción, y solo porque sus clientes siguen atascados en el pasado.