Learn how to use the <tbody> element to group main data rows in an HTML table, enabling better styling, accessibility, and structural clarity.
What it is
The <tbody> (Table Body) element groups the body content of a table. It contains the actual data rows (<tr>) that represent the core information, distinct from headers (<thead>) or footers (<tfoot>). While browsers often implicitly create a <tbody> if one is missing, explicitly defining it allows for precise CSS targeting and JavaScript manipulation. A single table can contain multiple <tbody> sections, which is useful for grouping related data sets within one visual table structure.
Why it matters
- CSS Styling: You can apply alternating row colors (zebra striping) or specific borders only to data rows without affecting headers.
- Accessibility: Screen readers understand the semantic structure, helping users navigate large datasets more efficiently.
- JavaScript Manipulation: It is easier to select, hide, or sort specific groups of rows by targeting their parent
<tbody>. - Print Layouts: Browsers may repeat
<thead>on each page when printing long tables, but<tbody>ensures the data flows correctly beneath those repeated headers.
Syntax or steps
To use <tbody>, place it inside the <table> element after any <caption> or <colgroup>. Inside <tbody>, define your data rows using <tr> and cells using <td>. If you need multiple groups, simply add additional <tbody> elements sequentially.
Example
<table>
<thead>
<tr>
<th>Name</th>
<th>Role</th>
</tr>
</thead>
<tbody>
<tr>
<td>Alice</td>
<td>Developer</td>
</tr>
<tr>
<td>Bob</td>
<td>Designer</td>
</tr>
</tbody>
<tbody>
<tr>
<td>Charlie</td>
<td>Manager</td>
</tr>
</tbody>
</table>
In this example, the first <tbody> contains Alice and Bob, while the second <tbody> contains Charlie. This separation allows you to style the "Management" section differently from the "Staff" section using CSS selectors like tbody:nth-child(2).
Common mistakes
- Nesting errors: Placing
<tbody>outside the<table>tag. It must be a direct child of<table>. - Missing closing tags: Forgetting to close
</tbody>before starting a new one or ending the table. - Confusing with
<tr>: Remember that<tbody>wraps rows; it does not replace them. Each row still needs its own<tr>. - Implicit vs. Explicit: Relying on browser auto-generation makes debugging harder. Always write explicit
<tbody>tags for clarity.
When to use it
| Scenario | Recommended Element | Reason |
|---|---|---|
| Column titles | <thead> |
Defines header context for screen readers. |
| Main data rows | <tbody> |
Groups the primary content logically. |
| Totals/Summaries | <tfoot> |
Often placed at the bottom visually but defined early in code. |
Practice
Guided Exercise: Create a table with three employees. Group the first two in one <tbody> and the third in another. Apply a light gray background to the second <tbody> using CSS.
Challenge: Write JavaScript that hides all rows in the first <tbody> when a button is clicked. Hint: Use document.querySelectorAll('tbody:first-of-type tr').
Quick check
Question: Can a table have more than one <tbody> element?
Answer: Yes, a table can contain multiple <tbody> elements to group different sets of data rows.
Summary
The <tbody> element is essential for structuring HTML tables semantically. By explicitly grouping data rows, you improve maintainability, enable targeted styling, and enhance accessibility for users relying on assistive technologies.