Tables arrange two-dimensional data in rows and columns. Use them only for real tabular data (numbers, comparisons, schedules)—not for general page layout. For layouts, use CSS Grid or Flexbox.
Key terms (quick glossary)
<table>- The root element that wraps the whole grid.
<caption>- The table’s title or summary; should be the first child of
tablewhen you use it. <thead>,<tbody>,<tfoot>- Optional sections: header rows, body rows, footer rows (e.g. totals). They group rows for semantics, styling, and printing.
<tr>(table row)- One horizontal row of cells.
<th>(table header cell)- A header cell—usually column or row labels. Default styling is often bold; meaning is “header,” not just bold text.
<td>(table data cell)- An ordinary data cell.
scopeonthscope="col"marks a column header;scope="row"marks a row header. Helps assistive tech associate headers with data cells.colspan- Makes one cell span multiple columns to the right.
rowspan- Makes one cell span multiple rows downward.
<colgroup>/<col>- Describe columns for styling or hints (e.g. column widths); optional.
Example 1 — Semantic table with caption and sections
Below: the HTML source, then the rendered table as users would see it.
<table>
<caption>Quarterly revenue (USD millions)</caption>
<thead>
<tr>
<th scope="col">Quarter</th>
<th scope="col">Product A</th>
<th scope="col">Product B</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">Q1</th>
<td>12</td>
<td>9</td>
</tr>
<tr>
<th scope="row">Q2</th>
<td>14</td>
<td>11</td>
</tr>
</tbody>
</table>
Rendered output
| Quarter | Product A | Product B |
|---|---|---|
| Q1 | 12 | 9 |
| Q2 | 14 | 11 |
Example 2 — colspan (merge cells across columns)
Use colspan="N" when one header or cell should cover N columns. Keep layouts simple—if you need many merged cells, consider splitting into smaller tables.
<table>
<thead>
<tr>
<th colspan="2" scope="colgroup">North</th>
<th colspan="2" scope="colgroup">South</th>
</tr>
<tr>
<th scope="col">A</th>
<th scope="col">B</th>
<th scope="col">A</th>
<th scope="col">B</th>
</tr>
</thead>
<tbody>
<tr><td>1</td><td>2</td><td>3</td><td>4</td></tr>
</tbody>
</table>
Rendered output
| North | South | ||
|---|---|---|---|
| A | B | A | B |
| 1 | 2 | 3 | 4 |
Example 3 — rowspan (merge cells down rows)
Use rowspan="N" when one cell should cover N rows. The next rows must omit cells that are already “filled” by the spanning cell.
<table>
<tbody>
<tr>
<th rowspan="2" scope="rowgroup">AM</th>
<td>Stand-up</td>
</tr>
<tr>
<td>Planning</td>
</tr>
<tr>
<th scope="row">PM</th>
<td>Deep work</td>
</tr>
</tbody>
</table>
Rendered output
| AM | Stand-up |
|---|---|
| Planning | |
| PM | Deep work |
Styling tables (CSS basics)
border-collapse: collapse— shared borders between cells (clean grid).separateleaves gaps unless you remove them withborder-spacing.- Borders and padding — apply to
th/td(or use classes on those cells) so the grid reads clearly. - Width — set
table { width: 100%; }ormax-widthso layout is predictable; usetable-layout: fixedif you want equal columns. - Responsive behavior — wrap wide tables in a container with
overflow-x: auto(horizontal scroll on small screens). Another option is reflowing content into lists or cards at narrow breakpoints.
What developers get wrong
- Layout tables: resurrecting
<table>for grids breaks zoom, semantics, and flex/grid adoption—maintain CSS layout skills separately. - Silent headers: styling
tdto look bold instead of markingth—screen readers cannot infer header relationships from font-weight. - Colspan gymnastics: irregular grids confuse linearized reading orders; reorganize content or split tables before merging half the matrix.
- Sorting/filtering SPA tables: DOM reordering without updating focus traps or captions—keyboard users lose context; manage focus and programmatic labels.
Accessibility reminders
- Screen readers often read tables in source order—keep rows and columns meaningful when linearized.
- For complex tables, associate headers with cells using
headersontd/thand matchingidon headers, or usescopeconsistently. - Avoid extreme colspan/rowspan mazes; simpler tables are easier for everyone.
Important interview questions and answers
- Q: What makes image delivery accessible and performant?
A: Meaningful `alt`, correct intrinsic `width`/`height`, and responsive sources (`srcset`/`sizes` or `picture`) based on viewport needs. - Q: When do you use a table in HTML?
A: Only for real tabular data, not page layout; use `th`, `scope`, and `caption` to preserve structure for assistive tech. - Q: What is the role of the `head` element in production apps?
A: It provides critical metadata like charset, viewport, title, canonical/social tags, and linked resources used by browsers and crawlers.
Challenge
Table headers
- Build a 3×3 table with
<th scope="col">. - Add a
<caption>describing the data.
Done when: screen readers can associate headers with cells.