HTML Guides for colgroup
Learn how to identify and fix common HTML validation errors flagged by the W3C Validator — so your pages are standards-compliant and render correctly across every browser. Also check our Accessibility Guides.
A row in this table has more cells than its <colgroup> and <col> elements declare, so some of its cells sit past the last column the markup defines.
When a table has column markup, that markup sets the column count before any row is read. Each <col> adds one column, or as many as its span attribute says. A <colgroup> with no <col> inside adds the number in its own span, which defaults to 1. A row is X columns wide when its cells add up to X, with each cell counting as many columns as its colspan. The validator reports this error once for every row wider than the Y columns the markup declares.
A common cause is an empty <colgroup></colgroup> that a table editor or template writes into every table. It still counts as one column, so every row of a table with two or more columns triggers the error. Another cause is a column added to the rows but not to the <colgroup>. Browsers still show the extra cells, but styles set on <col>, such as width or background-color, don't reach the columns the markup leaves out.
To fix it, declare every column the rows use: add the missing <col> elements, raise the span, or remove a <colgroup> that doesn't style anything.
Invalid example
The <colgroup> declares one column, but each row has two cells:
<table>
<colgroup>
<col class="item">
</colgroup>
<tr>
<th>Item</th>
<th>Price</th>
</tr>
<tr>
<td>Coffee</td>
<td>2.50</td>
</tr>
</table>
Valid example
One <col> for each column in the rows:
<table>
<colgroup>
<col class="item">
<col class="price">
</colgroup>
<tr>
<th>Item</th>
<th>Price</th>
</tr>
<tr>
<td>Coffee</td>
<td>2.50</td>
</tr>
</table>
A row in this table has fewer cells than its <colgroup> and <col> elements declare, so the row ends before the last column the markup defines.
Column markup sets the column count before any row is read. Each <col> adds one column, or as many as its span attribute says, and a <colgroup> with no <col> inside adds the number in its own span. A row is X columns wide when its cells add up to X, counting each cell's colspan and any cell from a row above that reaches down with rowspan. The validator reports this error once for every row narrower than the Y columns the markup declares. When no row reaches column Y at all, it also reports that table column Y established by element col (or colgroup) has no cells beginning in it.
A common cause is a column deleted from the rows while its <col> stays in the <colgroup>, for example after removing a column in a visual table editor. Without column markup, a short row only gets a warning. With it, the validator reports an error.
To fix it, make the column markup and the rows agree. If the column is gone, remove its <col> or lower the span. If the column should stay, add the missing cells to each short row, with an empty <td></td> where there is no data. A colspan on the last cell of a short row also clears this error, but when no row has a cell that starts in the last column, the validator then reports that column as having no cells.
Invalid example
The <colgroup> declares four columns, but each row has three cells:
<table>
<colgroup>
<col class="item">
<col class="size">
<col class="price">
<col class="stock">
</colgroup>
<tr>
<th>Item</th>
<th>Size</th>
<th>Price</th>
</tr>
<tr>
<td>T-shirt</td>
<td>M</td>
<td>15.00</td>
</tr>
</table>
Valid example
The <col> for the removed column is gone, so the markup declares three columns:
<table>
<colgroup>
<col class="item">
<col class="size">
<col class="price">
</colgroup>
<tr>
<th>Item</th>
<th>Size</th>
<th>Price</th>
</tr>
<tr>
<td>T-shirt</td>
<td>M</td>
<td>15.00</td>
</tr>
</table>
This table's <col> elements declare more columns than its rows fill, so column N has no <td> or <th> starting in it.
Each <col> inside a <colgroup> adds one column to the table, or as many columns as its span attribute says. The HTML table model then requires every column to have at least one cell that begins in it. A cell that only reaches the column through colspan doesn't count: with <col span="3"> and a row of <td>Alice</td><td colspan="2">2019</td>, column 3 is still reported.
The usual cause is column markup that no longer matches the content, such as a template that always writes the same <colgroup>, or a column removed from every row but left in the <colgroup>. Rows shorter than the column markup also trigger a companion error, "A table row was 2 columns wide, which is less than the column count established using column markup (3)".
To fix it, make the column markup match the rows. Remove the extra <col> elements or lower their span, or add the missing cells if that column should hold data.
Invalid example
Three <col> elements, but every row has only two cells:
<table>
<colgroup>
<col class="name">
<col class="role">
<col class="year">
</colgroup>
<tr>
<th>Name</th>
<th>Year</th>
</tr>
<tr>
<td>Alice Moreno</td>
<td>2019</td>
</tr>
</table>
Valid example
The <colgroup> declares the same two columns the rows use:
<table>
<colgroup>
<col class="name">
<col class="year">
</colgroup>
<tr>
<th>Name</th>
<th>Year</th>
</tr>
<tr>
<td>Alice Moreno</td>
<td>2019</td>
</tr>
</table>
The <col> elements in this table declare more columns than the rows use, and no <td> or <th> begins in the reported range.
Each <col> inside a <colgroup> adds one column to the table, or as many columns as its span attribute says, so <col span="4"> declares four. The HTML table model requires every column to have at least one cell that starts in it. A cell that only crosses a column through colspan doesn't count. With <col span="4"> and rows made of <th colspan="4">, or of <td> followed by <td colspan="3">, cells start only in columns 1 and 2, and the validator reports columns 3 and 4 together as the range 3…4.
This often happens in layout tables that declare a fine grid in the <colgroup> and then merge those columns with colspan in every row. It also happens when the rows are shorter than the column markup, which adds a second error: "A table row was 2 columns wide, which is less than the column count established using column markup (4)". When only one column is empty, the validator names that single column ("Table column 4") instead of a range.
To fix it, declare only the columns the rows use. Remove <col> elements or lower their span, and reduce the colspan values to match. Deleting the <colgroup> alone isn't enough: the oversized colspan then creates the empty columns itself, and the validator reports them as established by th or td instead.
Invalid example
The <col> declares four columns, but cells start only in the first two:
<table>
<colgroup>
<col span="4">
</colgroup>
<tr>
<th colspan="4">Opening hours</th>
</tr>
<tr>
<td>Monday</td>
<td colspan="3">9:00 to 17:00</td>
</tr>
</table>
Valid example
Two columns in the <colgroup>, and a cell starts in each of them:
<table>
<colgroup>
<col class="day">
<col class="hours">
</colgroup>
<tr>
<th colspan="2">Opening hours</th>
</tr>
<tr>
<td>Monday</td>
<td>9:00 to 17:00</td>
</tr>
</table>
Validate at scale.
Ship accessible websites, faster.
Automated HTML & accessibility validation for large sites. Check thousands of pages against WCAG guidelines and W3C standards in minutes, not days.
1K Weekly
1,000 monthly checks. Cancel anytime.
Get 1K Weekly →Join teams across 40+ countries