What is the purpose for HTML's tbody?
To give semantic meaning to your table:
<table>
<thead>
<tr>
<th>Person</th>
<th>Amount</th>
<th>Date</th>
</tr>
</thead>
<tbody>
<tr>
<td>Person1</td>
<td>$5.99</td>
<td>02/03/09</td>
</tr>
<tr>
<td>Person2</td>
<td>$12.99</td>
<td>08/15/09</td>
</tr>
</tbody>
</table>
According to the specification:
Table rows may be grouped into a table head, table foot, and one or more table body sections, using the THEAD, TFOOT and TBODY elements, respectively. This division enables user agents to support scrolling of table bodies independently of the table head and foot. When long tables are printed, the table head and foot information may be repeated on each page that contains table data.
The table head and table foot should contain information about the table's columns. The table body should contain rows of table data.
When present, each THEAD, TFOOT, and TBODY contains a row group. Each row group must contain at least one row, defined by the TR element.
Besides the important semantic importance of this (think screen readers), you can then easily style your headers apart from your data rows. Another relevant example is jQuery plugins such as the Tablesorter (original, archived) plugin can then easily figure out what your data structure looks like.
One great use I've found for tbody is to allow for the rows to be scrollable while keeping the column header and footer visible. This only works in browsers that actually support css though. Sorry no Internet Explorer!
<tbody style="height: 150px; overflow-y: scroll">
What if the header of the table is the first column in every row? In that case there's no way to specify the header of the table. It will actually break the HTML since the parser will assume that everything is part of the body of the table.
And why exactly is that tag necessary since the th specifies the header fields - the browser can find out which part of the table is the header by these fields.
What's the point of thead and tbody? They work for some cases and break the HTML in other cases. They duplicate the functionality of th. They complicate the code and may cause problems - Before I knew about tbody I assumed that tr-s are children of table.