According to the HTML DTD this is the content model for HTML tables:
<!ELEMENT TABLE - -
(CAPTION?, (COL*|COLGROUP*), THEAD?, TFOOT?, TBODY+)>
<!ELEMENT CAPTION - - (%inline;)* -- table caption -->
<!ELEMENT THEAD - O (TR)+ -- table header -->
<!ELEMENT TFOOT - O (TR)+ -- table footer -->
<!ELEMENT TBODY O O (TR)+ -- table body -->
<!ELEMENT COLGROUP - O (COL)* -- table column group -->
<!ELEMENT COL - O EMPTY -- table column -->
<!ELEMENT TR - O (TH|TD)+ -- table row -->
<!ELEMENT (TH|TD) - O (%flow;)* -- table header cell, table data cell-->
So this is illegal syntax:
<thead><th>Heading of table</th></thead>
It should be:
<thead><tr><th>Heading of table</th></tr></thead>
<th>
elements aren't required anywhere. They're simply one of the two cell types (the other being <td>
) that you can use in a table row. A <thead>
is an optional table section that can contain one or more rows.
Edit: As to why to use <thead>
there are several reasons:
- Semantic: You're differentiating between the content of your table and "metadata". This is most often used to delineate between column headers and data rows;
- Accessibility: it helps people who use screen readers to understand the contents of the table;
- Non-Screen Media: Printing a multi-page table may allow you to put the
<thead>
contents at the top of each page so people can understand what the columns meaning without flicking back several pages;
- Styling: CSS can be applied to
<tbody>
elements, <thead>
elements, both or some other combination. It gives you something else to write a selector against;
- Javascript: this often comes up when using jQuery and similar libraries. The extra information is helpful in writing code.
As an example of (5) you might do this:
$("table > tbody > tr:nth-child(odd)").addClass("odd");
The <thead>
element means those rows won't be styled that way. Or you might do:
$("table > tbody > tr").hover(function() {
$(this).addClass("hover");
}, function() {
$(this).removeClass("hover");
});
with:
tr.hover { background: yellow; }
which again excludes the <thead>
rows.
Lastly, many of these same arguments apply to using <th>
elements over <td>
elements: you're indicating that this cell isn't data but a header of some kind. Often such cells will be grouped together in one or more rows in the <thead>
section or be the first cell in each row depending on the structure and nature of your table.