<table>
The <table> element renders a grid of tabular data. It contains structural children — <thead>, <tbody>, rows (<tr>) and cells (<th>/<td>) — that the browser lays out into aligned columns and rows.
Definition
The <table> element represents tabular data — a two-dimensional grid of rows and columns whose cells hold values that relate to one another by position. It is a container element: on its own it displays nothing, and its meaning comes entirely from the structural children nested inside it. The browser reads that nesting and computes an aligned grid from it, sizing every column to fit its widest cell.
A <table> is built from a fixed set of child elements. Rows are <tr> elements; the cells within a row are either header cells (<th>) or data cells (<td>); and the rows may be grouped by role into a <thead> for the heading and a <tbody> for the body. An optional <caption>, placed first, gives the grid an accessible title. Understanding which child does what is the whole of using the element correctly.
Syntax
<table>
<caption>...</caption>
<thead>
<tr><th>...</th></tr>
</thead>
<tbody>
<tr><td>...</td></tr>
</tbody>
</table>
Parameters
| Element | Role |
|---|---|
<thead> | Groups the heading rows. Optional, but marks which rows are column labels and lets a printed table repeat its header across pages. |
<tbody> | Groups the body rows — the repeating data records. A table may hold several tbody groups to section long data. |
<tr> | A table row: one horizontal line of the grid. The number of cells in a row helps fix how many columns the table has. |
<th> | A header cell that labels a column or a row. Rendered bold and centred, and exposed to assistive tech as a heading via its scope. |
<td> | A data cell holding a single value. The ordinary cell of the body, sitting under the <th> that names its column. |
These children nest in a fixed order: a <caption> first if present, then an optional <thead>, then one or more <tbody> groups; each group holds <tr> rows, and each row holds <th> or <td> cells. Keeping the header cells in <th> and the values in <td> is what makes the grid meaningful to both the browser and a screen reader.
Return value
There is no return value — this is markup — but the rendered effect is precise and worth stating exactly. The browser lays the children out as a grid: each <tr> becomes one horizontal row, and the cells within align into vertical columns shared across every row. Column widths are computed from content: each column grows to fit its widest cell so that values line up top-to-bottom. Header cells (<th>) default to bold, centred text; data cells (<td>) to normal, left-aligned text. The <caption> renders above the grid as its title, and <thead>/<tbody> grouping is invisible on screen but drives print header repetition and the accessibility tree.
- Rows stack vertically in source order; the first
<tr>is the top line of the grid. - Columns are implicit — they are formed by cells at the same position across rows, and each sizes to its widest content.
- By default cells have no visible border; add
borderCSS withborder-collapse: collapseto draw the grid lines.
Examples
Minimal table: one header row, one data row
<table>
<tr><th>Name</th><th>Age</th></tr>
<tr><td>Ada</td><td>36</td></tr>
</table>
A full table with thead, tbody and a caption
The complete, rendering version — grouped rows, a caption, and border CSS so the grid lines are visible:
A table titled with a <caption>
The <caption> must be the first child of <table>; the browser renders it above the grid as the table's accessible name:
A striped table with nth-child CSS
Zebra striping is presentation, so it stays in CSS: tbody tr:nth-child(even) shades alternate body rows without touching the markup:
Grouping rows with multiple <tbody> sections
A single table may carry several <tbody> groups to section related records — here one group per team, each a labelled band of body rows:
Browser & runtime support
The <table> element and its children are part of the HTML standard and are supported in every browser without exception or prefixes — the element predates CSS itself. What has changed over the years is *how* tables are styled: border-collapse, border-spacing and per-cell padding replaced the old border, cellpadding and cellspacing attributes, which are obsolete. Keep the structure in HTML and move all presentation to CSS.
Frequently asked questions
What elements can go inside a table?
<caption> first, then an optional <thead>, one or more <tbody> groups (and optionally <tfoot>), each containing <tr> rows, and each row containing <th> header cells or <td> data cells.How does the browser decide column widths in a table?
Why does my table have no borders?
th, td { border: 1px solid #999 } together with table { border-collapse: collapse } on the table to draw single grid lines.