HTML Guide for table
Table rows on the same <table> element must have the same number of columns, which comes determined by the first tr row.
For example, this table is wrong as the first row defines 2 columns, while the second row tries to use 4 columns:
<table>
<tr>
<td>Liza</td>
</tr>
<tr>
<td>Jimmy</td>
<td>14</td>
</tr>
</table>
A <table> contains a <tr> row that has less <td> columns than the column count established by the first row. Check the table to ensure all rows have the same number of columns.
For example, in the following table, the first <tr> row defines that it’s 2 columns wide, but the second <tr> row tries to use only 1 column:
<table>
<!-- This first row sets the table as 2 columns wide -->
<tr>
<td>First</td>
<td>Second</td>
</tr>
<!-- This second row has only 1 column -->
<tr>
<td>Wrong</td>
</tr>
</table>
The <table> element does not accept a height attribute. Use CSS instead.
The W3C HTML Validator issue “Misplaced non-space characters inside a table” usually occurs when there are text nodes (or other elements) that are not properly placed within table elements. In HTML, all text content should be contained within table cells.
How to Fix the Issue
To resolve this issue, ensure that all text content is placed inside <td> or <th> elements, which are the valid child elements of <table>, <tr>, and related elements. Here’s how you can identify and fix the issue:
Example of Incorrect Table Structure
<table>
<tr>
Hello World <!-- This is misplaced content -->
<td>First Cell</td>
<td>Second Cell</td>
</tr>
</table>
Corrected Table Structure
<table>
<tr>
<td>Hello World</td> <!-- All text should be inside <td> or <th> -->
<td>First Cell</td>
<td>Second Cell</td>
</tr>
</table>
Guidelines
-
Text Content: Ensure that all text (including any headers or titles) is wrapped in <td> (for data cells) or <th> (for header cells). Keep in mind that event the non-breaking space character ( ) counts as text.
-
Table Structure: Remember a typical structure for a table includes <table> containing one or more <tr> elements, which in turn contain the <td> or <th> elements.
-
No Direct Text Nodes: Avoid having any direct text nodes outside of the cell elements within the table.
A table row tr has been found, containing no td cells. Check the table and remove empty rows.
Table contents is organized in rows using the <tr> element, which must contain cells using the <td> element, as in this example:
<table>
<thead>
<tr>
<th>Name</th>
<th>Age</th>
</tr>
</thead>
<tbody>
<tr>
<td>Liza</td>
<td>12</td>
</tr>
<tr>
<td>Jimmy</td>
<td>14</td>
</tr>
</tbody>
</table>
A tr with no td cells on it will raise an issue, as in this example:
<table>
<thead>
<tr>
<th>Name</th>
<th>Age</th>
</tr>
</thead>
<tbody>
<tr>
</tr>
<tr>
<td>Jimmy</td>
<td>14</td>
</tr>
</tbody>
</table>
Note that self-closing <tr/> elements also count as empty rows as are like <tr></tr>.
An <a> element has been found in an invalid place within a <table> element.
For example, the following code would cause this issue:
<table>
<tr>
<a href="#">link</a>
</tr>
</table>
Instead, the <a> element should be inside a <td> element, as a <tr> can’t hold content directly:
<table>
<tr>
<td>
<a href="#">link</a>
</td>
</tr>
</table>
Ensure each column in your table has at least one <td> or <th> cell starting in it. This error often occurs when using the colspan or rowspan attributes incorrectly.
Example of correct usage:
<table>
<tr>
<th>Header 1</th>
<th>Header 2</th>
</tr>
<tr>
<td>Row 1, Cell 1</td>
<td>Row 1, Cell 2</td>
</tr>
<tr>
<td>Row 2, Cell 1</td>
<td>Row 2, Cell 2</td>
</tr>
</table>
Incorrect usage example:
<table>
<tr>
<th>Header 1</th>
<th>Header 2</th>
</tr>
<tr>
<td colspan="2">Row 1, Cell 1</td>
</tr>
<tr>
<td>Row 2, Cell 1</td>
<!-- Missing cell in column 2 -->
</tr>
</table>
The corrected version ensuring each column has a starting cell:
<table>
<tr>
<th>Header 1</th>
<th>Header 2</th>
</tr>
<tr>
<td colspan="2">Row 1, spanning both columns</td>
</tr>
<tr>
<td>Row 2, Cell 1</td>
<td>Row 2, Cell 2</td>
</tr>
</table>
A <table> contains an incoherent number of cells on one of its columns. Check the structure of the table to find the invalid column.
Example of a valid table that defines in its header that the first column is 2 cells wide:
<table>
<thead>
<tr>
<th colspan="2">The table header</th>
</tr>
</thead>
<tbody>
<tr>
<td>The table body</td>
<td>with two columns</td>
</tr>
</tbody>
</table>
This same table with an empty body will be invalid because the table header cannot match any body columns:
<table>
<thead>
<tr>
<th colspan="2">The table header</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
A <table> contains an incoherent number of columns on one of its rows. Check the structure of the table to find the invalid row.
For example, in the following table, the first <tr> row defines that it’s 2 columns wide, but the second <tr> row tries to use 5 columns by means of a colspan attribute:
<table>
<!-- This first row sets the table as 2 columns wide -->
<tr>
<td>First</td>
<td>Second</td>
</tr>
<!-- This second row tries to use 5 columns -->
<tr>
<td colspan="5">Wrong</td>
</tr>
</table>
The <th> HTML element defines a cell as a header of a group of table cells, and must appear within a <tr> element.
In the following example for a simple table, the first <tr> contains two <th> header cells naming the values for each column:
<table>
<tr>
<th>Name</th>
<th>Age</th>
</tr>
<tr>
<td>Liza</td>
<td>49</td>
<tr>
<tr>
<td>Joe</td>
<td>47</td>
</tr>
</table>
The <caption> element specifies the caption (or title) of a table. It’s not allowed for a <caption> to contain another table.
To resolve the W3C Validator issue regarding the obsolete summary attribute on the table element, you should remove the summary attribute and instead provide a description of the table structure using a caption element.
Here’s how you can fix it:
- Remove the summary attribute: This attribute is no longer supported in modern HTML standards.
- Add a caption element: This element gives a brief description of the table, making it accessible and informing users what the table represents.
Example Before and After
Before Fixing (with obsolete summary attribute)
<table summary="This table shows the sales data for the year.">
<tr>
<th>Month</th>
<th>Sales</th>
</tr>
<tr>
<td>January</td>
<td>$1000</td>
</tr>
<tr>
<td>February</td>
<td>$1200</td>
</tr>
</table>
After Fixing (with caption element)
<table>
<caption>Sales Data for the Year</caption>
<tr>
<th>Month</th>
<th>Sales</th>
</tr>
<tr>
<td>January</td>
<td>$1000</td>
</tr>
<tr>
<td>February</td>
<td>$1200</td>
</tr>
</table>
Additional Option: Using a figure Element
If you want to provide a more extensive description alongside your table, you can wrap the table in a figure element.
Example with figure
<figure>
<figcaption>Sales Data for the Year</figcaption>
<table>
<tr>
<th>Month</th>
<th>Sales</th>
</tr>
<tr>
<td>January</td>
<td>$1000</td>
</tr>
<tr>
<td>February</td>
<td>$1200</td>
</tr>
</table>
</figure>
Both <table> and <td> elements no longer accept a width attribute. Instead, you should use CSS as in this example:
<table style="width:100%;">
<tr>
<td style="width:50px;">Name</td>
</tr>
</table>