Table Elements - HTML reference 2026 vdsology
- Chapter 7 — Table Elements
Chapter 7 — Table Elements
Tables represent tabular data — information with meaningful relationships between rows and columns. They must never be used for visual layout.
7.1 — <table> — Table Container
The root element. Content must appear in a strict order.
No element-specific attributes (all presentational attributes are obsolete — use CSS).
Required content order:
<caption>(optional, must be first if present)<colgroup>elements (zero or more)<thead>(optional, zero or one)<tbody>(zero or more) and/or<tr>elements<tfoot>(optional, zero or one)
7.2 — <caption> — Table Caption
The title or description of the table. Must be the first child of <table>.
No element-specific attributes.
<table>
<caption>Q1 2026 Sales by Region (in £ thousands)</caption>
<!-- ... -->
</table>
For accessibility, if <caption> is not visible, use aria-label or aria-labelledby on <table> instead.
7.3 — <colgroup> and <col> — Column Groups
<colgroup> groups columns for styling. <col> represents individual columns within a group.
<colgroup> attribute:
| Attribute | Values | Purpose |
|---|---|---|
span |
Integer (1–1000) | Number of columns this group spans (when no <col> children) |
<col> attribute:
| Attribute | Values | Purpose |
|---|---|---|
span |
Integer (1–1000) | Number of columns this element represents |
<table>
<colgroup>
<col style="width: 40%"> <!-- Column 1: 40% -->
<col span="3" style="width: 20%"> <!-- Columns 2-4: 20% each -->
</colgroup>
<!-- ... -->
</table>
7.4 — <thead>, <tbody>, <tfoot>
All three: No element-specific attributes — globals only.
| Element | Purpose |
|---|---|
<thead> |
Header rows — repeated on each page when printing |
<tbody> |
Body rows — the main data. Multiple <tbody> allowed. |
<tfoot> |
Footer rows — summary/totals. Appears last in source but browsers may render it after header and before body. |
<table>
<thead>
<tr>
<th scope="col">Month</th>
<th scope="col">Revenue</th>
<th scope="col">Expenses</th>
</tr>
</thead>
<tbody>
<tr>
<td>January</td>
<td>£42,000</td>
<td>£31,000</td>
</tr>
</tbody>
<tfoot>
<tr>
<th scope="row">Total</th>
<td>£42,000</td>
<td>£31,000</td>
</tr>
</tfoot>
</table>
7.5 — <tr> — Table Row
A row of cells. Contains <th> and/or <td> elements.
No element-specific attributes.
7.6 — <th> — Header Cell
A header cell — describes the cells in a column or row.
Element-specific attributes:
| Attribute | Values | Purpose |
|---|---|---|
scope |
col, row, colgroup, rowgroup |
What the header applies to — essential for accessibility |
colspan |
Integer 1–1000 | Span this many columns |
rowspan |
Integer 0–65534 | Span this many rows. 0 = span to end of row group |
headers |
Space-separated IDs | IDs of <th> elements that are headers for this cell |
abbr |
String | Abbreviated label for the header (screen readers use this for repeated reads) |
scope values:
col— This header applies to all cells below it in the same columnrow— This header applies to all cells to its right in the same rowcolgroup— This header applies to all cells in the column grouprowgroup— This header applies to all cells in the row group
<table>
<thead>
<tr>
<th scope="col">Product</th>
<th scope="col">Q1</th>
<th scope="col">Q2</th>
<th scope="col">Q3</th>
<th scope="col">Q4</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">Widget</th>
<td>£10k</td>
<td>£12k</td>
<td>£14k</td>
<td>£16k</td>
</tr>
</tbody>
</table>
7.7 — <td> — Data Cell
A data cell within a table.
Element-specific attributes:
| Attribute | Values | Purpose |
|---|---|---|
colspan |
Integer 1–1000 | Span this many columns |
rowspan |
Integer 0–65534 | Span this many rows. 0 = to end of row group |
headers |
Space-separated IDs | IDs of header cells for complex tables |
Spanning algorithm:
colspan="1"is default (no merging)rowspan="1"is default (no merging)rowspan="0"spans to the end of the current row group- Maximum:
colspan≤ 1000,rowspan≤ 65534
<!-- Spanning example -->
<table>
<caption>Schedule</caption>
<thead>
<tr>
<th scope="col">Time</th>
<th scope="col">Monday</th>
<th scope="col">Tuesday</th>
<th scope="col">Wednesday</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">9:00</th>
<td colspan="2">Team Meeting (Mon–Tue)</td>
<td>Code Review</td>
</tr>
<tr>
<th scope="row">10:00</th>
<td rowspan="2">Deep Work (Mon, 10–12)</td>
<td>Sprint Planning</td>
<td rowspan="2">Documentation (Wed, 10–12)</td>
</tr>
<tr>
<th scope="row">11:00</th>
<td>1:1 Meetings</td>
</tr>
</tbody>
</table>
7.8 — Table Accessibility Patterns
Pattern 1: Simple table with column headers
<table>
<caption>Browser market share 2026</caption>
<thead>
<tr>
<th scope="col">Browser</th>
<th scope="col">Market Share</th>
</tr>
</thead>
<tbody>
<tr><td>Chrome</td><td>63%</td></tr>
<tr><td>Safari</td><td>19%</td></tr>
<tr><td>Firefox</td><td>4%</td></tr>
</tbody>
</table>
Pattern 2: Table with both row and column headers
<table>
<caption>Pricing table</caption>
<thead>
<tr>
<td></td><!-- empty corner cell -->
<th scope="col" id="basic">Basic</th>
<th scope="col" id="pro">Pro</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row" id="storage">Storage</th>
<td headers="basic storage">1 GB</td>
<td headers="pro storage">50 GB</td>
</tr>
<tr>
<th scope="row" id="users">Users</th>
<td headers="basic users">1</td>
<td headers="pro users">25</td>
</tr>
</tbody>
</table>
Pattern 3: Complex table with headers attribute
<table>
<caption>Quarterly revenue by product and region</caption>
<thead>
<tr>
<th id="product" rowspan="2" scope="col">Product</th>
<th id="region" colspan="2" scope="colgroup">Region</th>
</tr>
<tr>
<th id="uk" scope="col">UK</th>
<th id="eu" scope="col">EU</th>
</tr>
</thead>
<tbody>
<tr>
<th id="widget" scope="row">Widget</th>
<td headers="widget uk">£42k</td>
<td headers="widget eu">€67k</td>
</tr>
</tbody>
</table>
Tags: #html #vdsology #webdevelopment #vdsologyhtml #html5 #htmlreference #htmlreference2026
Write a comment