Tables
Introduction
Tables present tabular data: spreadsheets, pricing grids, schedules, and comparison charts. HTML tables are for data, not for page layout. This chapter covers basic structure, headers, captions, merged cells, and accessibility habits you will use in real projects.
Prerequisites
Basic Table Structure
| Element | Role |
|---|---|
<table> | Table container |
<tr> | Table row |
<th> | Header cell |
<td> | Data cell |
<th> is for column or row labels; <td> is for values.
Table Sections: thead, tbody, tfoot
Split structure for clarity and styling:
| Section | Typical content |
|---|---|
<thead> | Column headers |
<tbody> | Main data rows |
<tfoot> | Totals, summaries |
Browsers can repeat header/footer rows when printing long tables (with CSS).
Captions
<caption> titles the table for everyone:
<table>
<caption>Team members and roles</caption>
...
</table>Place <caption> immediately after <table>. It appears above the grid by default (CSS can move it).
scope for Accessibility
scope tells assistive tech how a header relates to cells:
<th scope="col">Name</th>
<th scope="col">Email</th><th scope="row">Alice</th>
<td>alice@example.com</td>| Value | Meaning |
|---|---|
col | Header for a column |
row | Header for a row |
colgroup / rowgroup | Advanced grouped headers |
Without scope, simple tables still work, but complex tables become harder for screen readers to navigate.
Merging Cells: colspan and rowspan
Span columns
<tr>
<th colspan="2">Contact info</th>
<th>Status</th>
</tr>
<tr>
<td>Email</td>
<td>you@example.com</td>
<td>Active</td>
</tr>colspan="2" makes one cell cover two columns.
Span rows
<tr>
<th rowspan="2">Dept</th>
<th>Name</th>
<th>Hours</th>
</tr>
<tr>
<td>Engineering</td>
<td>40</td>
</tr>Use merging sparingly. Over-complicated tables are hard to read and to make responsive.
Multi-Level Headers
For very complex tables, also consider headers + id on cells (advanced accessibility). Most learning projects stay with scope.
Aligning Numeric Data
HTML does not have a number-alignment attribute in modern practice. CSS handles it:
<td class="num">1280.50</td>.num {
text-align: right;
font-variant-numeric: tabular-nums;
}Right-aligned numbers with tabular figures make columns easy to scan. Mention CSS here; full styling comes in a CSS track.
Do Not Use Tables for Layout
Old sites used tables for columns and sidebars. That harms:
- accessibility (linearized order is confusing)
- responsive design
- maintenance
Use semantic layout (header, main, section) and CSS Grid/Flexbox instead.
Warning
Data Only
If the content is not a grid of related facts, it is not a table. A product marketing page with three cards is not <table> material.
Large and Responsive Tables
Wide tables overflow small screens. Common patterns:
- Horizontal scroll — wrap table in a scrollable container (CSS)
- Simplify — hide non-critical columns on mobile (CSS)
- Card layout — rebuild rows as stacked blocks on narrow viewports (CSS + duplicate structure sparingly)
HTML provides the data grid; responsive behavior is mostly CSS. Keep headers honest so screen readers still understand the grid on desktop.
Complete Example
Mini Exercise
Create a table for three programming languages with columns: Language, Typing, Use case. Add:
<caption><thead>and<tbody>scopeon headers- One row header (
scope="row") if you use row labels
Open DevTools and confirm the table node contains tr → th/td only where expected.
FAQ
Can I put <table> inside <p>?
No. Tables are block-level. Place them under a heading in a section.
Are borders part of HTML?
Default borders are minimal. Borders and zebra striping are CSS (border, border-collapse, :nth-child).
When should the first column be <th scope="row">?
When the first cell in each row is a row label (product name, date, region). Data values stay <td>.
How many columns are too many?
If users must scroll horizontally on a laptop, consider fewer columns, a summary view, or a different visualization.
What comes next?
Form basics — collecting user input with <form>, labels, and controls.