Las tablas HTML muestran datos tabulares con filas y columnas. Debes elegir usar un <table> según el contenido que muestres y las necesidades de tus usuarios en relación con ese contenido. Si los datos se presentan, comparan, ordenan, calculan o se hace una referencia cruzada, es probable que <table> sea la opción correcta.
Si te interesa organizar contenido no tabular, como un grupo grande de imágenes en miniatura, las tablas no son adecuadas. En su lugar, crea una lista de imágenes y aplica un diseño de cuadrícula con CSS.
En esta sección, analizamos todos los elementos que componen la tabla, junto con algunas funciones de accesibilidad y usabilidad que se deben tener en cuenta cuando se presentan datos tabulares. Si bien Learn HTML no se enfoca en CSS, abordaremos algunas propiedades de CSS específicas de las tablas. Para obtener más información sobre CSS, consulta Learn CSS.
Elementos de la tabla, en orden
La etiqueta <table> contiene el contenido de la tabla, incluidos todos los elementos de la tabla.
El rol ARIA implícito de un <table> es table; las tecnologías de asistencia saben que este elemento es una estructura de tabla que contiene datos organizados en filas y columnas. Si la tabla mantiene un estado de selección, tiene navegación bidimensional o permite que el usuario reordene el orden de las celdas, establece role="grid".
Si las filas de grid se pueden expandir y contraer, usa role="treegrid" en su lugar.
Dentro de <table>, encontrarás los encabezados de la tabla (<thead>), los cuerpos de la tabla (<tbody>) y, de manera opcional, los pies de página de la tabla (<tfoot>). Cada uno de estos se compone de filas de la tabla (<tr>). Las filas contienen celdas de encabezado de la tabla (<th>) y de datos de la tabla (<td>) que, a su vez, contienen todos los datos.
En el DOM, antes de todo esto, puedes encontrar dos funciones adicionales: el título de la tabla (<caption>) y los grupos de columnas (<colgroup>). Según si el <colgroup> tiene un atributo span o no, puede contener elementos anidados de columna de tabla (<col>).
Los elementos secundarios de la tabla son, en orden, los siguientes:
- Elemento
<caption> - Elementos
<colgroup> - Elementos
<thead> - Elementos
<tbody> - Elementos
<tfoot>
Analizaremos los elementos secundarios de <table>, que son todos opcionales, pero recomendados, y, luego, veremos las filas, las celdas de encabezado de la tabla y las celdas de datos de la tabla. La <colgroup> se tratará al final.
Leyenda de la tabla
El método preferido para nombrar una tabla es el elemento semántico, <caption>.
El objeto <caption> proporciona un título de tabla descriptivo y asociado de forma programática.
Está visible y disponible para todos los usuarios de forma predeterminada.
El elemento <caption> debe ser el primer elemento anidado en el elemento <table>. Incluirla permite que todos los usuarios conozcan el propósito de la tabla de inmediato sin tener que leer el texto circundante. Como alternativa, puedes usar aria-label o aria-labelledby en el <table> para proporcionar un nombre accesible como leyenda. El elemento <caption> no tiene atributos específicos del elemento.
La leyenda aparece fuera de la tabla. La ubicación del subtítulo se puede establecer con la propiedad caption-side de CSS, que es una mejor práctica que usar el atributo align obsoleto. Esto puede establecer el subtítulo en la parte superior e inferior. Las posiciones laterales, con inline-start y inline-end, aún no se admiten por completo. La parte superior es la presentación predeterminada del navegador.
De preferencia, las tablas de datos deben tener encabezados y leyendas claros, y ser lo suficientemente explícitas como para no requerir más explicaciones. Ten en cuenta que no todos los usuarios tienen las mismas capacidades cognitivas. Cuando la tabla "demuestra un punto" o necesita interpretación, proporciona un breve resumen del punto o la función principal de la tabla. La ubicación de ese resumen depende de su longitud y complejidad.
Si es breve, úsalo como el texto interno de la leyenda. Si es más largo, resúmelo en el título y proporciona el resumen en el párrafo anterior a la tabla, asociando ambos con el atributo aria-describedby. Otra opción es colocar la tabla en un <figure> y el resumen en el <figcaption>.
Seccionamiento de datos
El contenido de las tablas se compone de hasta tres secciones: cero o más encabezados de tabla (<thead>), cuerpos de tabla (<tbody>) y pies de tabla (<tfoot>). Todos son opcionales y se admiten cero o más de cada uno.
Estos elementos no ayudan ni dificultan la accesibilidad de la tabla, pero son útiles en términos de usabilidad. Proporcionan enlaces de diseño. Por ejemplo, el contenido del encabezado se puede fijar, mientras que el contenido de <tbody> se puede desplazar. Las filas que no están anidadas en uno de estos tres elementos contenedores se incluyen de forma implícita en un <tbody>. Los tres comparten el mismo rol implícito rowgroup.
Ninguno de estos tres elementos tiene atributos específicos del elemento.
Esto es lo que tenemos hasta ahora:
<table>
<caption>MLW Students</caption>
<thead></thead>
<tbody></tbody>
<tfoot></tfoot>
</table>
Originalmente, se especificó que el elemento <tfoot> debía aparecer inmediatamente después del <thead> y antes del <tbody> por motivos de accesibilidad, por lo que es posible que te encuentres con este orden de origen no intuitivo en las bases de código heredadas.
Contenido de la tabla
Las tablas se pueden dividir en encabezados, cuerpos y pies de página, pero ninguno de estos elementos tiene una función real si las tablas no contienen filas, celdas ni contenido. Cada fila de la tabla, <tr>, contiene una o más celdas. Si una celda es de encabezado, usa <th>.
De lo contrario, usa <td>.
Por lo general, las hojas de estilo de los agentes de usuario muestran el contenido en una celda de encabezado de tabla <th> centrada y en negrita. Estos estilos predeterminados, y todos los demás, se controlan mejor con CSS en lugar de los atributos obsoletos que solían estar disponibles en celdas, filas e incluso la <table> individuales.
Había atributos para agregar padding entre celdas y dentro de ellas, para bordes y para la alineación del texto. El relleno y el espaciado entre celdas, que definen el espacio entre el contenido de una celda y su borde, y entre los bordes de las celdas adyacentes, respectivamente, se deben establecer con las propiedades border-collapse y border-spacing de CSS, respectivamente. Border-spacing no tendrá ningún efecto si se establece border-collapse: collapse. Si se configura border-collapse: separate;, es posible ocultar las celdas vacías por completo con empty-cells: hide;. Para obtener más información sobre cómo aplicar estilos a las tablas, consulta esta presentación interactiva de estilos CSS relacionados con las tablas.
En los ejemplos, agregamos un borde a la tabla y a cada celda individual con CSS para que algunas funciones sean más evidentes:
En este ejemplo, tenemos un título, un encabezado de tabla y un cuerpo de tabla. El encabezado tiene una fila que contiene tres celdas de encabezado <th>, lo que crea tres columnas. El cuerpo contiene tres filas de datos: la primera celda es una celda de encabezado para la fila, por lo que usamos <th> en lugar de <td>.
La celda <th> tiene un significado semántico, con roles ARIA implícitos de columnheader o rowheader. Define la celda como el encabezado de la columna o fila de celdas de la tabla, según el valor del atributo scope enumerado. El navegador usará col o row de forma predeterminada si scope no se establece de forma explícita.
Como usamos un lenguaje de marcado semántico, la celda 1956 tiene dos encabezados: Año y Lou Minious. Esta asociación nos indica que "1956" es el "año" de graduación de "Lou Minious". En este ejemplo, como podemos ver toda la tabla, la asociación es visualmente evidente.
El uso de <th> proporciona la asociación incluso cuando la columna o la fila del encabezado se desplazaron fuera de la vista. Podríamos haber establecido explícitamente <th scope="col">Year</th> y <th scope="row">Lou Minious</th>, pero, con una tabla como esta, los valores predeterminados enumerados funcionan.
Otros valores para scope incluyen rowgroup y colgroup, que son útiles con tablas complejas.
Combina celdas
Al igual que en MS Excel, Hojas de cálculo de Google y Numbers, es posible unir varias celdas en una sola. Esto se puede hacer con los atributos colspan y rowspan de HTML:
colspancombina dos o más celdas adyacentes dentro de una sola fila.rowspancombina celdas en filas cuando se agrega a la celda de la primera de las filas combinadas.
En este ejemplo, el encabezado de la tabla contiene dos filas. La primera fila de encabezado contiene tres celdas que abarcan cuatro columnas: la celda central tiene colspan="2". Esto combina dos celdas adyacentes. La primera y la última celda incluyen rowspan="2". Esto combina la celda con la celda de la fila adyacente, inmediatamente debajo de ella.
La segunda fila del encabezado de la tabla contiene dos celdas, que son las celdas de la segunda y la tercera columnas de la segunda fila. No se declara ninguna celda para la primera ni la última columna, ya que la celda de la primera y la última columna de la primera fila abarca dos filas.
En los casos en que una celda se define por varias celdas de encabezado con asociaciones que no se pueden establecer solo con los atributos scope, incluye el atributo headers con una lista de los encabezados asociados separados por espacios. Como este ejemplo es una tabla más compleja, definimos de forma explícita el alcance de los encabezados con el atributo scope. Para que sea aún más claro, agregamos el atributo headers a cada celda.
Es posible que los atributos headers no hayan sido necesarios en este caso, pero es importante recordarlos a medida que tus tablas se vuelven más complejas. Las tablas con estructuras complejas, como las tablas en las que se combinan encabezados o celdas, o con más de dos niveles de encabezados de columnas o filas, requieren la identificación explícita de las celdas de encabezado asociadas. En estas tablas complejas, asocia de forma explícita cada celda de datos con cada celda de encabezado correspondiente con una lista de valores id separados por espacios de todos los encabezados asociados como el valor del atributo headers.
El atributo headers se encuentra con mayor frecuencia en los elementos <td>, pero también es válido en <th>.
Dicho esto, las estructuras de tablas complejas pueden ser difíciles de comprender para todos los usuarios, no solo para los usuarios de lectores de pantalla. Desde el punto de vista cognitivo y en términos de compatibilidad con lectores de pantalla, las tablas más simples, con pocas o ninguna celda combinada, se comprenden mejor, incluso sin agregar encabezados ni alcance. También son más fáciles de administrar.
Cómo dar estilo a las tablas
Hay dos elementos relativamente oscuros que se mencionaron brevemente: el elemento del grupo de columnas, <colgroup>, y su único descendiente, el elemento de columna vacío <col>. El elemento <colgroup> se usa para definir grupos de columnas o elementos <col> dentro de una tabla.
Si se usa, la agrupación de columnas debe anidarse en <table>, inmediatamente después de <caption> y antes de cualquier dato de la tabla.
Si abarcan más de una columna, usa el atributo span.
Por lo general, el orden del esquema de contenido de una tabla es el siguiente, y <table> y <caption> son los dos elementos que se deben incluir:
<table>
<caption>Table Caption</caption>
<colgroup>
<col/>
</colgroup>
<thead>...
<colgroup> y <col> no tienen un significado semántico, lo que afectaría la accesibilidad de la tabla. Sin embargo, te ayudan a diseñar columnas con CSS, como establecer anchos.
Los estilos relacionados con <td> y <th> anulan los estilos de <col>. En CodePen, configuramos colspan para combinar algunas filas de la tabla, pero no todas. Si el selector de CSS nth-child se aplica a <tr>, según la fila o columna que se haya combinado, esto podría afectar el diseño.
Lamentablemente, solo se admiten algunas propiedades. Los estilos no se heredan en las celdas, y la única forma de segmentar celdas con <col> es usar un selector complejo, como el selector relacional :has().

Si tanto <table> como <colgroup> tienen un color de fondo, el background-color de <colgroup> se encuentra en la parte superior. El orden de dibujo es el siguiente: tabla, grupos de columnas, columnas, grupos de filas, filas, con las celdas al final y en la parte superior, como se muestra en el esquema de capas de la tabla.
Los elementos <td> y <th> no son descendientes de los elementos <colgroup> o <col>, y no heredan su diseño.
Para rayar una tabla, los selectores estructurales de CSS son muy útiles. Por ejemplo, tbody tr:nth-of-type(odd) {background-color: rgba(0 0 0 / 0.1);} agrega un negro translúcido a cada fila impar del cuerpo de la tabla, a la vez que permite que se muestren los efectos de fondo establecidos en <colgroup>.
Las tablas no son responsivas de forma predeterminada. En cambio, de forma predeterminada, se dimensionan según su contenido. Se necesitan medidas adicionales para que el diseño de la tabla funcione de manera eficaz en una variedad de dispositivos. Si cambias la propiedad de visualización CSS para los elementos de tabla, incluye atributos role de ARIA. Si bien esto puede sonar redundante, la propiedad display de CSS puede afectar el árbol de accesibilidad en algunos navegadores.
Presentar datos
Los elementos de tabla tienen significados semánticos que las tecnologías de asistencia usan para ayudar a los usuarios a navegar por las filas y columnas sin perderse. El elemento <table> no se debe usar para la presentación. Si necesitas un encabezado sobre una lista, usa un encabezado y una lista. Si deseas diseñar contenido en muchas columnas, usa el diseño de varias columnas.
Si quieres diseñar contenido en una cuadrícula, usa la cuadrícula de CSS.
Solo usa una tabla para los datos.
Piensa de esta manera: si tus datos requieren una hoja de cálculo para presentarse en una reunión, usa <table>. Si quieres usar las funciones disponibles en el software de presentaciones, como Presentaciones de Google o PowerPoint, es probable que necesites una lista de descripción.
En resumen, si no presentas datos tabulares, no uses un <table>.
Si usas una tabla para la presentación, configura role="none".
Muchos desarrolladores usan tablas para diseñar formularios, pero no es necesario. Sin embargo, debes conocer los formularios HTML.
Verifica tus conocimientos
Pon a prueba tus conocimientos sobre las tablas.
¿Qué elemento se usa para marcar las celdas que son encabezados?
<header><caption><th>¿Qué información es probable que sea adecuada para un diseño con una tabla?
<dl>.<ul>.