Learn how to present tabular data using HTML tables with proper structure including headers, body sections, and captions.
HTML tables are designed for displaying tabular data — information that naturally belongs in rows and columns, such as schedules, statistics, comparison charts, or financial data.
A table is built from several elements working together:
<table> — the container for the entire table<tr> — a table row<th> — a table header cell (bold and centered by default)<td> — a table data cell (regular content)Important: Tables should not be used for page layout. In the early days of the web, developers used tables to position content on the page, but this practice is outdated. Use CSS for layout and reserve tables for actual data.
<table>
<caption>Student Grades — Fall Semester</caption>
<thead>
<tr>
<th>Name</th>
<th>Subject</th>
<th>Grade</th>
</tr>
</thead>
<tbody>
<tr>
<td>Alice</td>
<td>Mathematics</td>
<td>A</td>
</tr>
<tr>
<td>Bob</td>
<td>Science</td>
<td>B+</td>
</tr>
<tr>
<td>Carol</td>
<td>English</td>
<td>A-</td>
</tr>
</tbody>
</table>A well-structured table is divided into logical sections:
<thead> wraps the header row(s). This tells the browser and assistive technologies which cells are column labels. When a long table is printed, some browsers repeat the <thead> on each page.
<tbody> wraps the main data rows. You can have multiple <tbody> elements to group rows into categories.
<tfoot> wraps footer rows, often used for totals or summaries. Browsers may render the footer at the bottom of the table regardless of where you place it in the markup.
<caption> provides a title or description for the table. It must be the first child of the <table> element. Captions are valuable for accessibility — screen readers announce the caption before reading the table data, giving users context about what the table contains.
Sometimes a cell needs to stretch across multiple columns or rows. HTML provides two attributes for this:
colspan — makes a cell span multiple columnsrowspan — makes a cell span multiple rows<table>
<tr>
<th colspan="2">Full Name</th>
<th>Age</th>
</tr>
<tr>
<td>First: Alice</td>
<td>Last: Smith</td>
<td>28</td>
</tr>
</table>In this example, the "Full Name" header spans two columns, aligning with the two name cells below it. Use these attributes sparingly — complex spanning can make tables harder to read and maintain.
What is the purpose of the <caption> element in a table?