The Complete Guide to HTML Tables
In the past, developers abused tables for website layouts. Today, we use them for their intended purpose: displaying tabular data. When used correctly, HTML tables are powerful, accessible, and easy to read. This guide covers the essential tags for building a well-structured data table.
The Core Structure: <table>, <tr>, <td>, and <th>
The Foundation: Every table is built from a few core elements that define its rows and cells.
<table>
: The main container for the entire table.<tr>
: Stands for "table row." It defines a horizontal row of cells.<td>
: Stands for "table data." This is a standard data cell.<th>
: Stands for "table header." This is a special header cell, which browsers typically render as bold and centered.
A Basic Table Structure:
<table>
<tr>
<th>Name</th>
<th>Role</th>
<th>Joined</th>
</tr>
<tr>
<td>Jane Doe</td>
<td>Developer</td>
<td>2021</td>
</tr>
</table>
Try it Yourself: Paste this code into the HTML Viewer. It works, but it's missing semantic structure that tells the browser which part is the header and which part is the body.
Adding Semantics: <thead> and <tbody>
The Problem: A basic table doesn't distinguish between its header rows and its data rows. This is bad for accessibility and can limit styling possibilities.
The Solution: Wrap your header row(s) in a <thead>
element and your data rows in a <tbody>
element.
A Semantically Correct Table:
<style>
table { width: 100%; border-collapse: collapse; }
th, td { border: 1px solid #ccc; padding: 8px; text-align: left; }
thead { background-color: #f2f2f2; }
</style>
<table>
<thead>
<tr>
<th>Name</th>
<th>Role</th>
<th>Joined</th>
</tr>
</thead>
<tbody>
<tr>
<td>Jane Doe</td>
<td>Developer</td>
<td>2021</td>
</tr>
<tr>
<td>John Smith</td>
<td>Designer</td>
<td>2022</td>
</tr>
</tbody>
</table>
Benefits of this structure: 1. Screen readers can now identify the header. 2. If the table is printed, the header can be repeated on each page. 3. You can easily style the header and body sections independently.
Advanced Cells: `colspan` and `rowspan`
The Concept: Sometimes you need a single cell to span across multiple columns or rows.
colspan="2"
: Makes a cell take up the width of two columns.rowspan="2"
: Makes a cell take up the height of two rows.
Example with `colspan`:
<table>
<thead>
<tr>
<th colspan="2">User Information</th>
</tr>
</thead>
<tbody>
<tr>
<td>Name</td>
<td>Jane Doe</td>
</tr>
</tbody>
</table>
Use Tables for Data, Not Layouts
With CSS Flexbox and Grid now widely supported, there is no reason to use tables for page layouts. Reserve them for what they do best: presenting tabular data in a clear, organized, and accessible way. By using semantic tags like <thead>
and <tbody>
, you create tables that are useful for all users and easy for browsers to understand.