The HTML rowspan attribute
The HTML rowspan attribute makes a <td> or <th> cell extend down through several rows. It takes a whole number from 0 to 65534 with a default of 1, and 0 means the cell runs to the end of its row group, although browser support for 0 is patchy.
Overview
The rowspan attribute sets how many rows a table cell occupies, counting its own row. It works on <td> and <th>, so a cell with rowspan="2" fills its own row and the one below it.
Valid values run from 0 to 65534. An invalid value falls back to 1, and larger numbers are clamped to 65534. Zero is a special value that the HTML Standard defines as spanning all remaining rows in the cell's row group, but MDN's compatibility data lists no Safari support for it, and for header cells it lists support only in Firefox.
The rows below a spanning cell must leave room for it. Each covered row needs one fewer cell in that column, because the spanning cell already fills the slot, and forgetting this pushes the extra cell into a new column at the end of the row.
A span never crosses into the next row group, so a cell in <tbody> cannot reach into a following <tfoot>. W3C's table tutorial marks a row header that covers several rows as a <th> with scope set to rowgroup and wraps those rows in their own <tbody>.
Syntax
<td rowspan="2">Spans two rows</td>
Values
| Value |
|---|
A whole number from 0 to 65534 (default 1). 0 spans the rest of the row group. |
Example
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Workshop schedule</title>
<style>
table { border-collapse: collapse; font: 14px sans-serif; }
th, td { border: 1px solid #cbd5e1; padding: 6px 10px; text-align: left; }
</style>
</head>
<body>
<table>
<caption>Workshop schedule</caption>
<tr><th scope="col">Time</th><th scope="col">Room A</th><th scope="col">Room B</th></tr>
<tr><th scope="row">9:00</th><td rowspan="2">CSS grid lab (2 hours)</td><td>Accessible forms</td></tr>
<tr><th scope="row">10:00</th><td>Image formats</td></tr>
<tr><th scope="row">11:00</th><td>Q&A</td><td>Q&A</td></tr>
</table>
</body>
</html>
Best practices
- Remove one cell from each row a span reaches into, or that row gains an extra column at the end.
- Write the real row count instead of
rowspan="0", which MDN's compatibility data lists as unsupported in Safari. - Keep each span inside a single <thead>, <tbody> or <tfoot>, since a span never crosses into the next group.
- Use
scope="rowgroup"on a header cell that spans a group of rows, and wrap those rows in their own<tbody>. - Recalculate or remove spans before sorting or filtering rows with JavaScript, because a moved row can leave a spanning cell covering the wrong data.
Accessibility
A row header that spans several rows needs its relationship made explicit. W3C's table tutorial marks such a header with scope="rowgroup", which only works when the rows it covers sit in their own row group.
Tables with multi-level headers need more than scope. The tutorial's page on them gives each header an id and lists the matching ids in the headers attribute of every data cell, and it suggests splitting such tables into smaller ones.
Frequently asked questions
What does rowspan mean in HTML?
How do I create a rowspan in an HTML table?
What does rowspan set to 0 do?
What is the maximum rowspan value?
Why does my rowspan add an extra column?
How do I set rowspan with JavaScript?
cell.rowSpan = 2. The property reflects the rowspan attribute and accepts values from 0 to 65534.