Tables: for data, not for layout
Why:A table is for when you really have rows and columns: prices, timetables, a comparison of plans. Afterwards you’ll build a table with headers and a caption, see how it differs from the old table layout, and know where a table belongs.
15 minutes
Read by speech synthesis (Qwen3-TTS); the voice is not a person’s.
A data table is a <table> for rows and columns, such as prices or a timetable, with a <caption> and <th> headers with a scope. It is not for layout.
A table for data
In the lesson on 1996 you saw tables stand in for a grid. But a table was invented for something else: data that has rows and columns. A timetable, prices, a comparison of plans, a list of documents with dates. In such a table a cell gets its meaning from its row and its column: “from $000” means a price because it sits in the Price column, in the Survey row.
A good test: take away the visible grid. Does the neighborly arrangement still carry meaning? For a menu on the left and text on the right it doesn’t: that’s layout. For a price and a service it does: that’s a table.
What a table is made of
<table>
<caption>What is included and what it costs</caption>
<thead>
<tr>
<th scope="col">Item</th>
<th scope="col">What is included</th>
<th scope="col">Price</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">Consultation</th>
<td>An hour on your documents</td>
<td>$000</td>
</tr>
</tbody>
</table> <caption>is the title: what the table is about. It comes first;<thead>and<tbody>are the head and the body. There is also<tfoot>for totals;<tr>is a row;<th>is a header cell, and<td>is a cell of data;scope="col"says the header applies to a column, andscope="row"that it applies to a row.
You can merge cells (colspan, rowspan), but complicated tables are painful for people who use a screen reader. If you can’t do without merging, it may really be two tables.
What a screen reader says
It’s th and scope that make a table make sense to someone listening to it. When the reading cursor lands on a cell, the software names the column and row headers along with it. Switch the table type in the diagram and pick cells.
| Item | What is included | Price |
|---|---|---|
The screen reader says: “Price: from £000. Row: First service.”
Column headers (th scope="col") and row headers (th scope="row") give every cell its context. A person who hears a single cell still knows what it is.
Check yourself: why use th when you could just make the cell bold?
Bold type is seen only by eyes. A th with a scope tells software that this is a header, and what it applies to.
Table or cards
Not everything that looks like a list should be a table. Choose like this:
- a table is for when the data is uniform and needs comparing: prices by plan, a timetable by day;
- cards or a list are for when the items stand alone and each has its own text: the description of a service, a review, a member of staff.
That’s why on our page the services live both in cards (the story) and in a table of prices (the comparison). It isn’t duplication: they are two ways of reading the same thing.
Tables and phones don’t get on well, because the columns don’t fit. The cure is to wrap the table in a block that scrolls sideways, not to shrink the type or turn the table into a picture. You’ll learn exactly how in the CSS part.
Practice
Add a table of prices or terms to the page. Your data is already there in the cards; carry the name, description and price over from them. If your project has no prices (a club, an event, a subscription service), make an “Opening hours” or “Timetable” table: columns for “Day” and “Time” are real data too.
This version stays in the 2005 era: data tables existed then, and people were already writing th and caption in them, though many forgot.
What was wrong with 2005
Data tables and layout tables were mixed up beyond telling apart: a page might have ten of them. Anyone who wanted a real table often fell into a trap: it, too, got nested inside a layout cell. And th with scope was rare in those days: they were used by those who thought about accessibility, and there were few such authors. Today the table in its true sense is alive, and layout with tables is not.
Practice
Preparing your page…
Test
Question 1 of 6
Cards
These cards go into your review once you finish the lesson.
When do you need a table?
Answer
When the data has both rows and columns: prices, a timetable, a comparison of plans. Never lay out blocks with a table.
What is a good table made of?
Answer
A caption, a thead with th scope=col headers, and a tbody of rows: each row has a th scope=row (the row header) and td cells (the data).
What does the scope attribute on th do?
Answer
It says what the header applies to: col for a column, row for a row. A screen reader announces a cell together with its headers.
What do you do with a wide table on a phone?
Answer
Let it scroll sideways inside its own block. Don’t shrink the type or replace the table with an image.
Sources
- HTML table basics (MDN) CC BY-SA, in English
- HTML table advanced features and accessibility (MDN) CC BY-SA, in English
- Tables Tutorial (W3C WAI) link only, in English
- Learn HTML: Tables (web.dev) CC BY, in English
Next
You now know: tables for data.