Topic 3.3
Spanning Rows and Columns
In one line
colspan stretches a cell across several columns and rowspan stretches it down several rows; each spanning cell takes over grid slots, so you must remove the cells it replaces.
Think of it like this
A school timetable. Most boxes hold one lesson in one period. But "Lunch break" covers the whole row, all days at once, and a double "Science lab" fills two periods in a row on Tuesday. On paper you rub out the lines between those boxes and make one big box. In HTML, colspan and rowspan do exactly that.
Words you'll meet
New words in this topic, in plain English. Come back here whenever one feels fuzzy.
- colspan
- An attribute that makes a cell as wide as several columns, like
colspan="3". - rowspan
- An attribute that makes a cell as tall as several rows, like
rowspan="2". - Slot
- One place in the table's grid, where one row meets one column.
- Grid
- The pattern of rows and columns the browser builds from your cells.
- Spanning cell
- A cell that covers more than one slot.
- cellIndex
- A cell's position among the cells written in its row (counting from 0), not its column on screen.
Step by step
01Sketch the grid first
Write the table as a grid of text. Mark which boxes join: here Lab covers Tuesday 9:00 and 10:00, and Lunch covers all three days at 11:00.
| Mon | Tue | Wed
9:00 | Maths | Lab | English
10:00 | Hindi | (Lab) | Maths
11:00 | Lunch ————————————————
12:00 | Art | Music | Sports02Write the rows that have no spans
The header row and the 12:00 row are plain: four cells each, one per column.
<tr><th>Time</th><th>Mon</th><th>Tue</th><th>Wed</th></tr>
...
<tr><th>12:00</th><td>Art</td><td>Music</td><td>Sports</td></tr>03Add the rowspan, then remove the cell it covers
The Lab cell starts in the 9:00 row with rowspan="2". In the 10:00 row, Tuesday's slot is already taken, so that row lists only three cells: the time, Monday and Wednesday.
<tr><th>9:00</th><td>Maths</td><td rowspan="2">Lab</td><td>English</td></tr>
<tr><th>10:00</th><td>Hindi</td><td>Maths</td></tr>04Add the colspan
Lunch covers three day-columns, so the 11:00 row has the time cell plus one cell with colspan="3": 1 + 3 = 4 slots, the right count.
<tr><th>11:00</th><td colspan="3">Lunch break</td></tr>05Check every row adds up
Count the slots per row: 9:00 has 4 cells; 10:00 has 3 cells plus 1 slot from Lab above = 4; 11:00 has 1 + 3 = 4; 12:00 has 4. Every row fills 4 columns, so the grid is clean.
Try it yourself
- 1
Make lunch shorter
In the timetable, change Lunch to
colspan="2". Predict what happens to Wednesday at 11:00 before you run. Then add a<td>Free</td>to fill the gap. - 2
Fix the ghost column
In the second example, delete the second
<td>Asha</td>. Predict the new cell count for row 3, then run and check the 4th column has gone. - 3
Add a third round
In the grid example, make
Roundspan 3 columns, add a<th>3</th>and a score for each player. Predict the printed grid first; every line should have 4 entries.
Code & diagrams
Wednesday's Maths is in the 4th column on screen, but its `cellIndex` is 2: it counts written cells, not columns.
Preview
Console
Nothing logged yet.Expected console output
Lab rowSpan: 2
Lunch colSpan: 3
Cells written in the 10:00 row: 3
cellIndex of Wednesday's Maths: 2Every row has 3 cells, which looks right, but row 3 forgot that `Asha` above already fills its first slot. Its cells shift right and `9` sticks out into a 4th column. Delete the second `<td>Asha</td>` to fix it.
Preview
Console
Nothing logged yet.Expected console output
Row 1 has 3 cells written
Row 2 has 3 cells written
Row 3 has 3 cells writtenThis is the browser's placement rule in a few lines of code: find the first free slot, then mark every slot the cell covers. A two-level header: `Round` spans two columns and `Player` spans two rows.
Preview
Console
Nothing logged yet.Expected console output
Player | Round | Round
Player | 1 | 2
Asha | 8 | 9
Ravi | 7 | 10Break it on purpose
Errors are the best teachers. Make each change, read the error, guess what went wrong, then reveal the answer.
Break #1
Add a rowspan but keep the covered cell
In the timetable, add <td>PE</td> back into the 10:00 row between Hindi and Maths.
Break #2
Span further than the section
Give Science lab rowspan="9" in a table with only four body rows.
Myth vs fact
Myth
colspan merges the contents of the cells next to it.
Fact
It only makes one cell wider. The cells it replaces must be removed from the HTML; any content in them has to go somewhere else.
Myth
cellIndex tells you which column a cell is in.
Fact
It is the cell's position among the cells written in its row. When a rowspan from above takes a slot, the two numbers differ (Wednesday's Maths had cellIndex 2 but sat in column 4).
Myth
A big table with many spans is more readable.
Fact
Each span makes the grid harder to follow, especially for screen reader users. Use spans when the data really groups that way; otherwise repeat the value or split the table.
Pro corner
Extra depth for experienced readers. New to this? Skip it for now and come back later.
- ▸
The HTML Living Standard defines the exact table processing model: slots are assigned with a "current column" that skips cells taken from above, which is the algorithm in the third live example. Overlapping cells are a "table model error"; browsers still render something, but results vary, so validate complex tables (validator.w3.org flags these).
- ▸
colspan="0"is not "to the end": it is treated as 1. Onlyrowspan="0"has the "to the end of the row group" meaning. - ▸
Screen readers read spanning headers for every slot they cover, so a
th colspan="2"over two sub-headers announces both levels ("Round, 1, 8"). Deep nesting (three or more header levels) gets confusing fast; consider splitting into several simpler tables. - ▸
Spans make JavaScript table work harder: sorting, filtering or highlighting a column must use a grid map like the one above, because
row.cells[i]is not column i. Data-grid libraries often forbid row spans in the body for this reason.
Remember this
- 1
Think of the table as a grid of slots: one slot where each row meets each column. Normally one cell fills one slot.
colspan="3"(column span) makes a cell fill 3 slots across, in its own row.rowspan="2"(row span) makes a cell fill 2 slots down: its own row and the row below. A cell can have both, and then it covers a rectangle. - 2
The golden rule: every slot is filled exactly once. When a cell spans 3 columns, its row needs 2 fewer cells. When a cell spans 2 rows, the next row needs one fewer cell, and you leave that cell out of the HTML completely. Forget to remove a cell and it gets pushed out to a new column on the right; remove too many and the row ends early with an empty gap.
- 3
How the browser places cells: it walks each row from left to right and puts each cell in the first free slot, skipping slots already taken by a
rowspanfrom above. That's why, in the row under a two-row cell, you write the cells as if the taken slot weren't there. - 4
Plan before you type. Draw the table on paper (or in a text file) as a grid, mark the big boxes, then write each row by listing only the cells that start in that row. Count: for every row, the sum of the
colspanvalues of its cells, plus the slots taken byrowspans from above, must equal the number of columns. - 5
Spans only stretch cells; they don't create or merge content. A spanning
thlabels every slot it covers: a header withcolspan="2"over "Morning" labels both columns under it. That's how two-level headers work ("Round" over "1" and "2"), and Topic 3.4 shows how to make those headers clear to screen readers. - 6
Limits from the HTML standard:
colspanmust be 1 to 1000 androwspan0 to 65534 (larger values are clamped).rowspan="0"means "to the end of this row group". A span never crosses from one row group into another, so arowspanintbodystops at the end of thattbody.
Explain it without notes
Explain what colspan and rowspan do, and what you must remove from the HTML when you use each.
How does the browser decide which column a cell lands in?
Why can cell.cellIndex differ from the column a cell appears in?
When should you avoid spans even if they would make the table look neater?
Practice
Build a 3-column table (Day, Morning, Evening) for two days where Saturday's single activity Trip covers both Morning and Evening.
Build a table where one teacher's name, Mrs Rao, covers two rows of subjects: Maths and Physics.
Trade-offs
- ↔
Spans make grouped data look clean and avoid repeating values, but they complicate sorting, filtering and screen reader navigation.
- ↔
Repeating a value in every row is easier to process and read cell by cell, but looks busier on screen.
Done when you can
I can make a cell span several columns or rows.
I can work out which cells to remove when I add a span.
I can plan a table as a grid and check each row adds up to the column count.
I can build a two-level header with
colspanandrowspan.I know why
cellIndexis not the same as the visual column.