The <thead>, <tbody> & <tfoot> elements
These three tags split a <table> into sections. <thead> holds the header rows with column titles, <tbody> holds the main data rows, and <tfoot> holds summary rows such as totals. They help screen readers and make styling easy, like keeping the header visible while the body scrolls.
Last updated: October 3, 2026
Quick facts
| Category | None of their own — they are only allowed inside a <table> |
| Content model | Zero or more <tr> elements |
| Tag omission | Optional in some cases (browsers even add <tbody> automatically), but writing all start and end tags is best practice |
| Permitted parents | A <table>: <thead> after any <caption>/<colgroup>, then <tbody>, then <tfoot> last |
| DOM interface | HTMLTableSectionElement (all three) |
Syntax
Live example
Edit the code below and watch the preview update instantly.
Attributes
| Attribute | Description |
|---|---|
| — | All three accept only the global attributes. Old attributes like align, valign and char are obsolete; use CSS instead. |
Common examples
A complete table with all three sections
Header row in thead, data in tbody, totals in tfoot.
Groups with several tbody elements
Each tbody can be a group, with its own header row.
A sticky header row
The header stays visible while scrolling through a long table.
Striped rows in the body only
Target tbody so header and footer rows aren’t striped.
Sectioned table vs rows only
A table made only of <tr> rows works, and the browser quietly adds a <tbody> for you. But without <thead>, nothing tells the browser which row is the header.
Explicit sections let header rows repeat on every printed page, make CSS such as sticky headers and striped bodies easy, and keep JavaScript sorting from moving your header row. They cost three extra tags — worth it for any real data table.
| With thead/tbody/tfoot | Rows only | |
|---|---|---|
| Header repeats when printed | Yes | No |
| Easy sticky header & stripes | Yes | Harder |
| Sorting scripts | Safe | May move the header |
Common mistakes to avoid
- Using thead instead of th. The header cells inside thead still need to be
<th>. - Putting tfoot in the wrong place. Today it should come after tbody (older guides said before; both work, but after reads naturally).
- More than one thead or tfoot. A table can have many tbody elements, but only one thead and one tfoot.
- Using sections for layout. Tables are for data; lay out pages with CSS grid or flexbox.
Accessibility & SEO tips
- Use
<th scope="col">in thead so screen readers announce the column name with each cell. - Wrap wide tables in a scrollable container so they don’t make the whole page scroll sideways on phones.
- Clear, well-structured tables are easy for search engines to understand and can be shown in featured snippets.
- For very long tables, consider splitting the body into several tbody groups with their own header rows — it makes the data far easier to scan.
Browser support
Supported in every browser, including Chrome, Edge, Firefox, Safari and their mobile versions — it has been part of HTML since the very first versions.
Tutorial: How to make a table