<table> Tag — DemoThis page shows how to build HTML tables: basic structure, rowspan and colspan, headers, and other features. Each example shows the output and the code.
A table is made of <table>, rows <tr>, and cells
<td> (table data). Each row has the same number of cells (unless you use colspan/rowspan).
| Cell A1 | Cell A2 |
| Cell B1 | Cell B2 |
<table>
<tr>
<td>Cell A1</td>
<td>Cell A2</td>
</tr>
<tr>
<td>Cell B1</td>
<td>Cell B2</td>
</tr>
</table>
<tr> = table row. <td> = table data (one
cell). Rows go top to bottom; cells in a row go left to right. The browser draws a grid. Use CSS
border-collapse: collapse and borders on th/td to get clear lines.
<thead> and <th>Use <thead> for the header section and <th> for header cells
instead of <td>. Put the body rows in <tbody>. This improves semantics and
accessibility.
| Name | Score |
|---|---|
| Ali | 85 |
| Sara | 92 |
<table>
<thead>
<tr>
<th>Name</th>
<th>Score</th>
</tr>
</thead>
<tbody>
<tr>
<td>Ali</td>
<td>85</td>
</tr>
<tr>
<td>Sara</td>
<td>92</td>
</tr>
</tbody>
</table>
<th> means “header cell” — browsers often render it bold.
<thead> groups the header row(s); <tbody> groups the data rows. Screen
readers use this structure. You can also use <tfoot> for a footer row (e.g. totals).
colspan: merge cells across columnscolspan="n" makes one cell span n columns. The next cells in that row
are skipped (the merged cell “uses up” their space).
| Full-width header (colspan="2") | |
|---|---|
| Col 1 | Col 2 |
<table>
<tr>
<th colspan="2">Full-width header (colspan="2")</th>
</tr>
<tr>
<td>Col 1</td>
<td>Col 2</td>
</tr>
</table>
colspan="2" means this single cell takes the space of two columns. So
in that row you only need one <th>; the second column is already “used” by the span. Use
colspan for section headers that sit above several columns (e.g. “Mid-term” over multiple subject
columns).
rowspan: merge cells across rowsrowspan="n" makes one cell span n rows. Rows below must have fewer
cells in that column (the merged cell “uses up” one slot in each of those rows).
| Side header (rowspan="3") | Row 1 |
|---|---|
| Row 2 | |
| Row 3 |
<table>
<tr>
<th rowspan="3">Side header (rowspan="3")</th>
<td>Row 1</td>
</tr>
<tr>
<td>Row 2</td>
</tr>
<tr>
<td>Row 3</td>
</tr>
</table>
rowspan="3" means this cell occupies three rows. In the first row you
have two cells (the spanning cell + “Row 1”). In the second and third rows you only add one
<td> each, because the first column is still “taken” by the rowspan. Use rowspan
for row labels (e.g. “January” next to three sub-rows).
colspan and rowspan togetherYou can use both in the same table. Plan the grid: a cell that has
colspan="2" rowspan="2" takes 2×2 cells; the rows below need one fewer cell in the first two columns.
| Big cell (2×2) | C | |
| F | ||
| G | H | I |
<table>
<tr>
<td colspan="2" rowspan="2">Big cell (2×2)</td>
<td>C</td>
</tr>
<tr>
<td>F</td>
</tr>
<tr>
<td>G</td>
<td>H</td>
<td>I</td>
</tr>
</table>
<caption>: table titleUse <caption> inside <table> to give the table a title. It is
usually shown above the table and helps screen readers and SEO.
| Student | Grade |
|---|---|
| Ali | A |
| Sara | B+ |
<table>
<caption>Student grades — Spring 2025</caption>
<thead>
<tr>
<th>Student</th>
<th>Grade</th>
</tr>
</thead>
<tbody>…</tbody>
</table>
<caption> should be the first child of
<table>. You can move it below the table with CSS: caption-side: bottom;. One
caption per table.
scope on <th> (accessibility)For screen readers, you can say whether a <th> is a header for its
row or its column using scope="col" or scope="row".
| Name | Math | English |
|---|---|---|
| Ali | 90 | 85 |
| Sara | 88 | 92 |
<tr>
<th scope="col">Name</th>
<th scope="col">Math</th>
<th scope="col">English</th>
</tr>
<tr>
<th scope="row">Ali</th>
<td>90</td>
<td>85</td>
</tr>
scope="col" means this header applies to all cells in the column
below (or to the right in RTL). scope="row" means it applies to the cells in the same row. Row
headers are common when the first column is labels (e.g. names). This helps assistive technologies announce
“Math, 90” instead of just “90”.
<table> → <tr> (rows) →
<td> (data) or <th> (header). Use <thead>,
<tbody>, and optionally <tfoot>.<table>.<th>, use scope="col" or scope="row"
for accessibility.