Tablas de datos en HTML: estructura y elementos | Nicolás Garzón
HTML
Copiar < table>
< caption> Ventas por mes</ caption>
< thead>
< tr>
< th scope = " col" > Mes</ th>
< th scope = " col" > Ventas</ th>
</ tr>
</ thead>
< tbody>
< tr>
< th scope = " row" > Enero</ th>
< td> $20.000.000</ td>
</ tr>
</ tbody>
</ table> table contiene el conjunto de datos y sus relaciones.
Una tabla es apropiada cuando una celda se interpreta mediante encabezados de fila, columna o ambos.
Alinear un formulario.
Construir una grid de cards.
Organizar un header.
Simular columnas visuales.
CSS Grid o Flexbox resuelven layout sin inventar relaciones tabulares.
HTML
Copiar < caption> Inventario por sucursal</ caption> Nombra o describe la tabla. Debe ser el primer hijo de table.
Una caption útil permite entender qué representan los datos antes de recorrer las celdas.
HTML
Copiar < caption> Tabla 1</ caption> HTML
Copiar < caption> Productos con stock inferior al mínimo</ caption> Representa una fila de celdas.
HTML
Copiar < th scope = " col" > Producto</ th>
< td> Teclado mecánico</ td>
th: celda de encabezado.
td: celda de datos.
No uses td y negrilla para simular un encabezado. th crea una relación semántica.
HTML
Copiar < thead>
< tr>
< th scope = " col" > Producto</ th>
< th scope = " col" > Precio</ th>
< th scope = " col" > Stock</ th>
</ tr>
</ thead> scope="col" indica que cada heading se aplica a las celdas de su columna.
HTML
Copiar < tbody>
< tr>
< th scope = " row" > Teclado</ th>
< td> $320.000</ td>
< td> 12</ td>
</ tr>
</ tbody> scope="row" relaciona el heading con los datos de esa fila.
HTML
Copiar < table>
< thead> ...</ thead>
< tbody> ...</ tbody>
< tfoot> ...</ tfoot>
</ table> Agrupan filas por función:
thead: encabezados principales.
tbody: cuerpo de datos.
tfoot: resumen o totales.
El navegador puede insertar tbody en el DOM aunque no aparezca en source.
HTML
Copiar < table>
< caption> Resumen de pedidos del día</ caption>
< thead>
< tr>
< th scope = " col" > Estado</ th>
< th scope = " col" > Cantidad</ th>
< th scope = " col" > Total</ th>
</ tr>
</ thead>
< tbody>
< tr>
< th scope = " row" > Pendientes</ th>
< td> 8</ td>
< td> $420.000</ td>
</ tr>
< tr>
< th scope = " row" > Completados</ th>
< td> 21</ td>
< td> $1.380.000</ td>
</ tr>
</ tbody>
< tfoot>
< tr>
< th scope = " row" > Total</ th>
< td> 29</ td>
< td> $1.800.000</ td>
</ tr>
</ tfoot>
</ table> HTML
Copiar < th colspan = " 2" scope = " colgroup" > Ingresos</ th> Hace que una celda ocupe varias columnas.
No significa automáticamente que el encabezado tenga una relación accesible correcta. En tablas complejas debes definir con precisión grupos y asociaciones.
HTML
Copiar < th rowspan = " 2" scope = " rowgroup" > Bogotá</ th> Extiende una celda por varias filas.
Las combinaciones de rowspan y colspan pueden hacer una tabla difícil de comprender, especialmente en mobile y con tecnologías de asistencia. Simplifica la estructura cuando sea posible.
HTML
Copiar < colgroup>
< col>
< col span = " 2" class = " numeric-column" >
</ colgroup> Permiten aplicar propiedades o agrupar columnas. No reemplazan headings ni relaciones de datos.
Una celda vacía puede ser válida si el dato realmente no existe, pero debe distinguirse de cero, “no aplica” o dato pendiente cuando esa diferencia importa.
HTML
Copiar < td> < span aria-label = " No aplica" > —</ span> </ td> No dependas únicamente de un símbolo ambiguo; explica la convención mediante caption, texto o contexto.
No reordenes columnas visualmente de forma distinta al DOM. Los encabezados y celdas deben mantener la misma relación en lectura, foco y presentación.
Un patrón básico conserva la tabla y permite scroll horizontal:
HTML
Copiar < div class = " table-container" tabindex = " 0" aria-label = " Tabla desplazable horizontalmente" >
< table> ...</ table>
</ div> El wrapper debe recibir foco solo cuando el scroll no es accesible de otra manera y necesita una indicación visible de que puede desplazarse.
Otra opción es reformular datos en cards para pantallas pequeñas, pero no ocultes relaciones ni dupliques contenido de forma inconsistente.
CSS
Copiar table, thead, tbody, tr, th, td {
display : block;
} Puede destruir la estructura visual y accesible de la tabla. Si transformas el layout, prueba el árbol de accesibilidad y la lectura de relaciones.
Un encabezado clickable para ordenar necesita un button dentro de th:
HTML
Copiar < th scope = " col" aria-sort = " ascending" >
< button type = " button" > Precio</ button>
</ th> aria-sort pertenece al heading de la columna ordenada y debe actualizarse mediante JavaScript.
La lógica de ordenamiento no forma parte del elemento table por sí sola.
HTML
Copiar < table>
< caption> Stock por producto</ caption>
< thead>
< tr>
< th scope = " col" > Producto</ th>
< th scope = " col" > Sucursal centro</ th>
< th scope = " col" > Sucursal norte</ th>
</ tr>
</ thead>
< tbody>
< tr>
< th scope = " row" > Café molido</ th>
< td> 14</ td>
< td> 8</ td>
</ tr>
< tr>
< th scope = " row" > Leche entera</ th>
< td> 22</ td>
< td> 19</ td>
</ tr>
</ tbody>
</ table>
Usar table para layout.
Crear encabezados con td y bold.
Omitir caption en una tabla que necesita contexto.
No definir scope en headings simples.
Combinar rowspan y colspan sin necesidad.
Tratar una celda vacía como un valor universal.
Convertir todo a display block y perder relaciones.
Reordenar visualmente columnas.
Hacer sortable un th sin un control interactivo real.
Ocultar columnas esenciales en mobile.
Table representa datos bidimensionales.
Caption identifica la tabla.
Th es una celda de encabezado; td, de datos.
Scope relaciona headings con filas o columnas simples.
Thead, tbody y tfoot agrupan filas por función.
Colspan y rowspan aumentan complejidad.
La adaptación responsive debe conservar relaciones.
Sorting necesita button, estado y JavaScript.
¿Por qué un td con <strong> no reemplaza a un th?
Respuesta Porque strong solo comunica importancia del texto. Th identifica una celda de encabezado y permite relacionarla semánticamente con los datos.
Encabezados, caption y tablas accesibles profundiza en relaciones simples y complejas.