On this page
HTML tables for organizing data
What are tables for?
HTML tables are designed to present tabular data in an organized way: information that makes sense in rows and columns, such as grades, schedules, price comparisons, or statistics.
It is important to understand that tables should NOT be used to create page layouts. That practice was common in the 2000s, but today we have CSS Flexbox and Grid for layout purposes.
Basic table structure
A complete table has this structure:
<table>
<caption>Descriptive table title</caption>
<thead>
<tr>
<th>Header 1</th>
<th>Header 2</th>
</tr>
</thead>
<tbody>
<tr>
<td>Data 1</td>
<td>Data 2</td>
</tr>
</tbody>
<tfoot>
<tr>
<td>Summary 1</td>
<td>Summary 2</td>
</tr>
</tfoot>
</table>Main elements
| Element | Function |
|---|---|
<table> |
Container for the entire table |
<caption> |
Title or description of the table |
<thead> |
Group of header rows |
<tbody> |
Group of data rows |
<tfoot> |
Group of summary or total rows |
<tr> |
A table row |
<th> |
A header cell (table header) |
<td> |
A data cell (table data) |
The caption element
The <caption> provides an accessible title for the table. It must be the first child of <table>:
<table>
<caption>Monthly plan pricing</caption>
<!-- ... -->
</table>Screen readers announce the caption before reading the table, which helps the user decide whether they want to explore the data.
Headers with scope
The scope attribute on <th> indicates whether the header applies to a column or a row:
<!-- Column header -->
<th scope="col">Price</th>
<!-- Row header -->
<th scope="row">Basic plan</th>This is essential for accessibility. Without scope, screen readers cannot correctly associate each cell with its corresponding header.
Merging cells (colspan and rowspan)
Sometimes you need a cell to span multiple columns or rows:
<table>
<thead>
<tr>
<th scope="col">Product</th>
<th scope="col" colspan="2">Price</th>
</tr>
<tr>
<th scope="col"></th>
<th scope="col">Monthly</th>
<th scope="col">Annual</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">Basic</th>
<td>$10</td>
<td>$100</td>
</tr>
<tr>
<th scope="row">Premium</th>
<td>$25</td>
<td>$250</td>
</tr>
</tbody>
</table>colspan="2"— The cell spans 2 columnsrowspan="3"— The cell spans 3 rows
Responsive tables
Tables can overflow on small screens. A simple solution is to wrap them in a container with horizontal scroll:
<div style="overflow-x: auto;">
<table>
<!-- Table with many columns -->
</table>
</div>This allows the user to scroll horizontally only within the table, without affecting the rest of the page.
Best practices for tables
- Always use
<caption>to describe the table's content - Use
<thead>,<tbody>, and<tfoot>to structure the table semantically - Add
scopeto<th>elements to improve accessibility - Do not use tables for layout — use CSS Grid or Flexbox
- Keep tables simple — if you need more than 2 levels of headers, consider splitting into smaller tables
Practice
- Build a schedule table: Create a table with
<caption>,<thead>,<tbody>, and<tfoot>that displays a weekly class schedule. Usescope="col"andscope="row"on the headers. - Merge cells: Modify your table so that at least one cell uses
colspanand another usesrowspan, simulating a schedule where a class spans two hours or two days. - Make it responsive: Wrap your table in a container with
overflow-x: autoand verify that it scrolls horizontally on small screens.
In the next lesson, we will dive deeper into semantic HTML and its impact on accessibility and SEO.
<table>
<caption>First quarter grades</caption>
<thead>
<tr>
<th scope="col">Student</th>
<th scope="col">Math</th>
<th scope="col">Science</th>
<th scope="col">Average</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">Anna Lopez</th>
<td>95</td>
<td>88</td>
<td>91.5</td>
</tr>
<tr>
<th scope="row">Carlos Ruiz</th>
<td>78</td>
<td>92</td>
<td>85</td>
</tr>
<tr>
<th scope="row">Maria Torres</th>
<td>86</td>
<td>90</td>
<td>88</td>
</tr>
</tbody>
<tfoot>
<tr>
<th scope="row">Overall average</th>
<td>86.3</td>
<td>90</td>
<td>88.2</td>
</tr>
</tfoot>
</table>
Sign in to track your progress