La tabla semántica: <table>, <tr>, <td>, <th> + scope, secciones y <caption>
Las tablas HTML representan datos tabulares: información organizada en filas y columnas donde la relación entre ambas tiene significado real. El precio de un producto en una categoría, el resultado de un equipo en una fecha, la temperatura de una ciudad en un mes — eso es una tabla.
<table>, <tr>, <td>: la estructura mínima
La tabla se construye fila por fila. Cada <tr> (table row) es una fila. Dentro de cada <tr> van las celdas: <td> (table data). Las columnas son implícitas — las determina la posición de cada celda en su fila.
<!-- Tabla mínima: 2 filas de datos, 3 columnas -->
<table>
<tr>
<td>HTML</td>
<td>Curso</td>
<td>Gratis</td>
</tr>
<tr>
<td>CSS</td>
<td>Curso</td>
<td>Gratis</td>
</tr>
</table>
Regla de anidado obligatoria:
<table>
└── <tr>
└── <td> o <th>
Toda celda vive dentro de un <tr>. Todo <tr> vive dentro de <table> (o de una sección). Poner un <td> directamente en <table> sin <tr> es HTML inválido.
<th> + scope: la celda de encabezado
<th> (table header) es semánticamente distinto de <td>. No es “una celda en negrita y centrada” — eso es CSS accidental del navegador. <th> comunica que esta celda describe a otras: nombra una columna o una fila.
El atributo scope declara la dirección del encabezado:
scope="col": este<th>encabeza una columna — las celdas que están por debajo de él.scope="row": este<th>encabeza una fila — las celdas que están a su derecha.
<!-- scope="col": los th de la primera fila encabezan columnas -->
<tr>
<th scope="col">Producto</th>
<th scope="col">Precio</th>
</tr>
<!-- scope="row": el th de cada fila de datos encabeza esa fila -->
<tr>
<th scope="row">Notebook</th>
<td>$800</td>
</tr>
<tr>
<th scope="row">Tablet</th>
<td>$400</td>
</tr>
Por qué scope importa para accesibilidad: cuando un lector de pantalla navega la celda $800 de la tabla de arriba, anuncia: “Precio, Notebook: $800” — el usuario recibe el valor con su contexto completo. Sin scope, el lector debe inferir la relación; con scope, es explícita e inequívoca.
Esta es la pieza de accesibilidad central del módulo — el equivalente de <label for> en formularios. En CAT-09 aprendimos que todo input visible necesita su label; aquí: toda tabla con relaciones fila↔columna debe declarar sus encabezados con <th scope>.
<thead>, <tbody>, <tfoot>: secciones de la tabla
Las filas se pueden agrupar en tres secciones según su rol:
<thead>: filas de encabezado — típicamente la primera fila con los<th scope="col">.<tbody>: filas de datos — el cuerpo de la tabla.<tfoot>: filas de pie — totales, promedios, sumas.
<table>
<thead>
<tr>
<th scope="col">Mes</th>
<th scope="col">Ventas</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">Enero</th>
<td>1.200</td>
</tr>
<tr>
<th scope="row">Febrero</th>
<td>980</td>
</tr>
</tbody>
<tfoot>
<tr>
<th scope="row">Total</th>
<td>2.180</td>
</tr>
</tfoot>
</table>
| Mes | Ventas |
|---|---|
| Enero | 1.200 |
| Febrero | 980 |
| Total | 2.180 |
Las secciones no son obligatorias para una tabla válida, pero mejoran la semántica: declaran el rol de cada grupo de filas y permiten a los lectores de pantalla navegar directamente al cuerpo de datos.
<caption>: el título accesible de la tabla
<caption> es el título de la tabla. Va como primer hijo de <table>, antes de cualquier sección.
<table>
<caption>Ventas por mes — primer semestre</caption>
<thead>
...
</thead>
<tbody>
...
</tbody>
</table>
Por qué es preferible a un <h> suelto encima de la tabla:
Un <h2> antes de la tabla es texto en el DOM, pero no tiene relación programática con ella. El lector de pantalla lo lee como un encabezado de sección, no como el nombre de la tabla.
<caption> está asociado a la tabla por el modelo de accesibilidad del navegador. Cuando el foco entra a la tabla, el lector de pantalla anuncia el caption como nombre de la tabla antes de que el usuario empiece a navegar las celdas.
La regla: toda tabla de datos tabulares debería tener un <caption> que permita saber qué representa la tabla sin leer sus celdas.
La tabla sin CSS se ve como texto organizado — los bordes y estilos visuales son del Bloque II. Lo que aprendemos aquí es la estructura semántica correcta.
Tu turno: construí una tabla “Comparativa de planes” con caption, thead con 3 encabezados de columna (scope="col"), y tbody con 3 filas donde cada una comienza con <th scope="row">. Luego hacé clic en “Comprobar”.
Tu primera tabla semántica
Armá una tabla semántica que muestre la comparativa de planes de un servicio ficticio. El sandbox pone el `<body>` — tu código va adentro. La tabla debe: 1. Tener un `<caption>` con el texto exacto: `Comparativa de planes`. 2. Tener un `<thead>` con una fila de encabezados de columna: - `<th scope="col">Característica</th>` - `<th scope="col">Básico</th>` - `<th scope="col">Pro</th>` 3. Tener un `<tbody>` con **exactamente 3 filas de datos**. En cada fila, la primera celda es un encabezado de fila (`<th scope="row">`): - Fila 1: `<th scope="row">Precio</th>` | `<td>$5/mes</td>` | `<td>$15/mes</td>` - Fila 2: `<th scope="row">Almacenamiento</th>` | `<td>10 GB</td>` | `<td>100 GB</td>` - Fila 3: `<th scope="row">Soporte</th>` | `<td>Email</td>` | `<td>24/7</td>`
Preview
En la referencia
En esta página