HTML Tutorial / Accessible Tables: caption, scope, and Spanning Cells
A readable data table identifies its subject and makes clear which row and column headings apply to each value. Use caption and th, add scope where it helps, and merge cells only when the resulting relationships remain understandable.
Name the table with caption
caption describes the table as a whole and belongs at the beginning of table. It differs from a nearby paragraph heading because it is part of the table. If a period or measurement method is needed to interpret the numbers, state it in the caption or nearby text. The caption introduces the table; individual row and column names still belong in header cells.
Connect data to headers with scope
Use scope="col" for column headings and scope="row" for row headings. In this example, the value at Monday and Morning is three visitors.
<table>
<caption>Visitors by day and time of day</caption>
<thead>
<tr>
<th scope="col">Day</th>
<th scope="col">Morning</th>
<th scope="col">Afternoon</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">Monday</th>
<td>3 visitors</td>
<td>5 visitors</td>
</tr>
<tr>
<th scope="row">Tuesday</th>
<td>4 visitors</td>
<td>6 visitors</td>
</tr>
</tbody>
</table>
| Day | Morning | Afternoon |
|---|---|---|
| Monday | 3 visitors | 5 visitors |
| Tuesday | 4 visitors | 6 visitors |
scope describes the direction of a header's relationship to data; it is not a visual styling rule. In a simple table, the relationship may be obvious without it, but explicit markup makes the intent easier to review. The W3C WAI tables tutorial explains further patterns.
Merge cells only when the data requires it
colspan="2" covers two columns; rowspan="2" covers two rows. The next example groups Morning and Afternoon under a shared heading. The colgroup defines those two columns so scope="colgroup" has a clear target.
<table>
<col>
<colgroup span="2"></colgroup>
<tr>
<th scope="col" rowspan="2">Day</th>
<th scope="colgroup" colspan="2">Visitors</th>
</tr>
<tr>
<th scope="col">Morning</th>
<th scope="col">Afternoon</th>
</tr>
<tr>
<th scope="row">Monday</th>
<td>3 visitors</td>
<td>5 visitors</td>
</tr>
</table>
Do not add merged cells simply to decorate a straightforward table. If readers have to guess which heading belongs to a number, simplify the table or split it into smaller tables. The W3C WAI guide to irregular table headers gives more complex examples.
Test the relationships
Point to any value and ask, “Which day and time does this represent?” Check the answer without relying only on color or position. Test narrow screens for clipped content and, for complex merged tables, try a screen reader as well. Tables should represent data, not a page layout or an input form.










