Fusión de celdas: colspan, rowspan (y cuándo NO usar tablas)
Con la tabla semántica de la lección anterior ya dominada, el siguiente paso es la fusión de celdas: colspan y rowspan permiten que una celda ocupe más de una columna o más de una fila.
Cuándo NO usar tablas: layout con tablas es LEGACY y está prohibido
Antes de ver la fusión de celdas, un punto conceptual importante.
En los años 90 y principios de los 2000, antes de que existieran herramientas de CSS para layout (ni floats, ni Flexbox, ni Grid), los desarrolladores usaban tablas HTML anidadas para construir la estructura visual de la página: el sidebar en una celda, el contenido principal en otra, el header en una fila superior, el footer abajo.
<!-- EJEMPLO DE LO QUE NO SE HACE — tabla de layout (LEGACY y PROHIBIDO) -->
<!-- Solo para ilustrar el error; no se practica ni se aprende como técnica -->
<table>
<tr>
<td colspan="2"><!-- header --></td>
</tr>
<tr>
<td><!-- sidebar --></td>
<td><!-- contenido --></td>
</tr>
<tr>
<td colspan="2"><!-- footer --></td>
</tr>
</table>
Por qué está prohibido hoy — tres razones concretas:
-
Semántica rota:
<table>anuncia “datos tabulares” al árbol de accesibilidad. Si la tabla es para layout y no hay datos tabulares, el lector de pantalla anuncia “tabla de N filas y M columnas” al usuario ciego — información incorrecta que genera confusión activa. -
Inaccesible: los lectores de pantalla navegan las tablas celda por celda. En una tabla de layout, el orden de lectura raramente coincide con el orden lógico del contenido — el usuario puede recibir el footer antes del contenido principal.
-
Frágil y difícil de mantener: las tablas de layout con múltiples niveles de anidado son extremadamente difíciles de modificar. Cambiar el diseño implica reescribir el HTML estructural, no solo los estilos CSS.
La regla simple:
Tabla = datos donde la relación fila↔columna tiene significado real. Si un dato pierde sentido cuando se saca de su fila y columna, probablemente es una tabla. Si lo que estás maquetando es la estructura visual de la página (header, sidebar, footer), usá Flexbox o Grid — eso se verá en el Bloque III.
colspan: fusión de columnas
colspan="N" hace que la celda ocupe N columnas.
<!-- El encabezado "Marcador" ocupa las columnas "Local" y "Visitante" -->
<tr>
<th scope="col">Partido</th>
<th scope="col" colspan="2">Marcador</th>
</tr>
<tr>
<td>Final</td>
<th scope="col">Local</th>
<th scope="col">Visitante</th>
</tr>
El efecto en el conteo de celdas: una fila de 3 columnas donde una celda tiene colspan="2" → esa fila tiene 2 elementos <td> literales en el HTML, aunque visualmente ocupa 3 columnas. La celda con colspan cuenta como 1 elemento DOM.
rowspan: fusión de filas
rowspan="N" hace que la celda ocupe N filas.
<!-- La celda "Matemática" ocupa Lunes y Martes en la columna Mañana -->
<tr>
<th scope="row">Lunes</th>
<td rowspan="2">Matemática</td>
<td>Historia</td>
</tr>
<tr>
<th scope="row">Martes</th>
<!-- No hay <td> para "Mañana" — la ocupa el rowspan de arriba -->
<td>Física</td>
</tr>
El efecto crítico en el conteo de celdas: la fila siguiente a una celda con rowspan="2" tiene menos elementos <td> literales que el número de columnas. Si ponés un <td> vacío en esa posición “para completar”, la grilla se descuadra.
| Día | Mañana | Tarde |
|---|---|---|
| Lunes | Matemática | |
| Martes | Inglés | Física |
| Miércoles | Historia | |
El modelo mental para los spans: contá los elementos <td> reales, no las columnas visuales.
- Lunes: 1
<td>(elcolspan="2"ocupa las 2 columnas de datos) - Martes: 2
<td>(rowspan="2"+ Física) - Miércoles: 1
<td>(Inglés ya ocupa la mañana desde la fila anterior) - Total en tbody: 4 elementos
<td>, aunque la tabla tiene 3 columnas de datos
Tu turno: construí el horario con caption “Horario semanal”, thead con 3 columnas (Día, Mañana, Tarde), y tbody con Lunes (colspan="2"), Martes (rowspan="2") y Miércoles. Prestá atención al conteo de <td> reales. Luego hacé clic en “Comprobar”.
Fusión de celdas
Armá una tabla de horario para un instituto ficticio. El sandbox pone el `<body>` — tu código va adentro. La tabla debe: 1. Tener un `<caption>` con el texto exacto: `Horario semanal`. 2. Tener un `<thead>` con una fila de encabezados de columna: - `<th scope="col">Día</th>` - `<th scope="col">Mañana</th>` - `<th scope="col">Tarde</th>` 3. Tener un `<tbody>` con **exactamente 3 filas** (Lunes, Martes, Miércoles): - **Fila Lunes:** `<th scope="row">Lunes</th>` + **una celda** con `colspan="2"` y texto `Matemática`. _(Matemática ocupa mañana Y tarde de Lunes — una sola celda con colspan=2)_ - **Fila Martes:** `<th scope="row">Martes</th>` + `<td rowspan="2">Inglés</td>` + `<td>Física</td>` _(Inglés se extiende también al miércoles por la mañana — rowspan=2)_ - **Fila Miércoles:** `<th scope="row">Miércoles</th>` + **solo** `<td>Historia</td>` _(Inglés ya ocupa la mañana del miércoles — no pongas otro td ahí)_
Preview
En la referencia
En esta página