Caption & Column Groups (<caption>, <colgroup>)
Two lesser-known table elements round out a fully structured table: <caption> gives the
whole table an accessible title, and <colgroup>/<col> let you style entire columns without
repeating CSS on every single cell.
<caption> — An Accessible Table Title
<caption> must be the first child of <table>, immediately after the opening tag. It
provides the table's accessible name — a screen reader announces it before reading any cell
content, similar to how a heading introduces a section.
<table>
<caption>Quarterly Revenue by Product Line (USD, millions)</caption>
<thead>
<tr>
<th scope="col">Product</th>
<th scope="col">Q1</th>
<th scope="col">Q2</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">Hardware</th>
<td>12.4</td>
<td>13.1</td>
</tr>
</tbody>
</table><h3>) is visually similar but not programmatically connected to the table. <caption> is the semantically correct choice — it is read as part of the table itself, and works correctly even if the table is later moved or embedded elsewhere on the page.<caption>, and it must come immediately after the opening <table> tag — before any <thead>, <colgroup>, or <tr>.Styling the Caption
caption {
caption-side: top; /* or "bottom" to place it below the table */
font-weight: 600;
text-align: left;
padding: 8px 0;
}<colgroup> and <col> — Column-Wide Styling
Normally, styling "every cell in this column" means writing a CSS selector like{' '}
td:nth-child(2) or repeating a class on every cell in that column. <colgroup> and{' '}
<col> let you describe column-level presentation once, directly in the table's markup.
<table>
<caption>Server Inventory</caption>
<colgroup>
<col style="background-color: #f5f5f5;">
<col span="2">
<col style="background-color: #fffbe6;">
</colgroup>
<thead>
<tr>
<th scope="col">Hostname</th>
<th scope="col">CPU</th>
<th scope="col">RAM</th>
<th scope="col">Status</th>
</tr>
</thead>
<tbody>
<tr>
<td>web-01</td>
<td>8 cores</td>
<td>32 GB</td>
<td>Online</td>
</tr>
<tr>
<td>web-02</td>
<td>8 cores</td>
<td>64 GB</td>
<td>Maintenance</td>
</tr>
</tbody>
</table>Attribute | Where | Purpose |
|---|---|---|
| Wraps one or more | Groups columns for shared styling |
span | On | How many columns this entry applies to (default 1) |
style / class | On | Only a small set of CSS properties actually apply (background, border, width, visibility) |
<colgroup> must appear right after <caption> (or right after the opening <table> tag if there's no caption) — before any <thead> or row content.The span Attribute
Rather than writing three separate <col> elements for three visually identical columns, use
span on a single <col> to cover a range.
<colgroup> <col> <!-- column 1: default --> <col span="3" style="background-color: #eef7ff;"> <!-- columns 2, 3, 4 share this style --> </colgroup>
<col> — mainly background, border, width, and visibility. Text properties like color or font-weight do not apply through <col> because column elements don't actually wrap any content — cell styles still win. Use column-based CSS selectors for anything beyond that limited set.A Common Practical Use: Fixed Column Widths
<table>
<colgroup>
<col style="width: 40%;">
<col style="width: 20%;">
<col style="width: 20%;">
<col style="width: 20%;">
</colgroup>
<thead>
<tr>
<th scope="col">Description</th>
<th scope="col">Qty</th>
<th scope="col">Unit Price</th>
<th scope="col">Total</th>
</tr>
</thead>
<tbody>
<tr>
<td>Wireless Mouse</td>
<td>2</td>
<td>$24.99</td>
<td>$49.98</td>
</tr>
</tbody>
</table><colgroup> is especially handy on invoices and reports, where you want consistent column proportions without repeating a width style on every single <td> in that column.Key Takeaways
<caption> gives a table an accessible title and must be the first child of <table>.
A table can have only one <caption>, distinct from a nearby heading element.
<colgroup>/<col> apply styling to entire columns without repeating it on every cell.
Only a limited set of CSS properties (background, border, width, visibility) actually apply through <col>.
span lets one <col> cover multiple columns at once.