HTML Tutorial
HTML Tables
Tables are rows of data: titres, marks, timetables. thead, th, and caption make that grid readable. Do not use tables to lay out a whole site.
When to use a table
A table is for data that belongs in rows and columns: scores, schedules, price lists, comparison charts. Each cell is a fact that lines up with a header. If you are placing a sidebar next to an article, that is layout. Use CSS, not a table.
Early websites used tables to draw entire pages. Screen readers, phones, and later edits all suffer. Build the page with headings, landmarks, and CSS grid or flexbox. Keep <table> for tabular data.
table, tr, th, and td
<table> wraps the grid. Each <tr> is a row. <th>is a header cell (a column or row label). <td> is a data cell. Header cells are announced as headers by assistive tech, so do not mark a score as th just to make it bold.
Example
<table>
<tr>
<th>Student</th>
<th>Quiz</th>
<th>Lab</th>
</tr>
<tr>
<td>Ada</td>
<td>18</td>
<td>20</td>
</tr>
<tr>
<td>Linus</td>
<td>15</td>
<td>19</td>
</tr>
</table>thead, tbody, and caption
<thead> groups the header row. <tbody> groups the data rows. A<caption> names the table for everyone, including people who never see a visual grid. Put the caption first inside the table.
Example
<table>
<caption>Week 3 lab scores</caption>
<thead>
<tr>
<th>Student</th>
<th>Quiz</th>
<th>Lab</th>
<th>Total</th>
</tr>
</thead>
<tbody>
<tr>
<td>Ada</td>
<td>18</td>
<td>20</td>
<td>38</td>
</tr>
<tr>
<td>Linus</td>
<td>15</td>
<td>19</td>
<td>34</td>
</tr>
<tr>
<td>Grace</td>
<td>20</td>
<td>20</td>
<td>40</td>
</tr>
</tbody>
</table>You can add <tfoot> for a totals row. Browsers may keep the footer in view when a long table prints. For a short scores table, thead and tbody are enough.
colspan and rowspan
colspan stretches a cell across columns. rowspan stretches it down rows. Use them when a label truly covers more than one cell. Do not merge cells to fake a layout.
Example
<table>
<caption>Scores by unit</caption>
<thead>
<tr>
<th>Student</th>
<th colspan="2">Unit 1</th>
</tr>
<tr>
<th></th>
<th>Quiz</th>
<th>Lab</th>
</tr>
</thead>
<tbody>
<tr>
<th rowspan="2">Ada</th>
<td>18</td>
<td>20</td>
</tr>
<tr>
<td>17</td>
<td>19</td>
</tr>
</tbody>
</table>Count the cells in each row. A header with colspan="2" already occupies two columns, so the row needs fewer th or td tags. Mismatched counts produce a crooked grid.
Borders belong in CSS
The old border attribute still works in some browsers, but CSS is the place to draw lines, pad cells, and stripe rows. border-collapse: collapse joins adjacent borders into a single line so the table looks like a spreadsheet instead of a stack of boxes.
Example
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Week 3 lab scores</title>
<style>
table {
border-collapse: collapse;
width: 100%;
}
th, td {
border: 1px solid #cbd5e1;
padding: 0.5rem 0.75rem;
text-align: left;
}
th {
background: #f1f5f9;
}
caption {
text-align: left;
font-weight: 700;
margin-bottom: 0.5rem;
}
</style>
</head>
<body>
<table>
<caption>Week 3 lab scores</caption>
<thead>
<tr><th>Student</th><th>Quiz</th><th>Lab</th><th>Total</th></tr>
</thead>
<tbody>
<tr><td>Ada</td><td>18</td><td>20</td><td>38</td></tr>
<tr><td>Linus</td><td>15</td><td>19</td><td>34</td></tr>
<tr><td>Grace</td><td>20</td><td>20</td><td>40</td></tr>
</tbody>
</table>
</body>
</html>This tutorial site styles table.data-table for lesson comparison charts. Your own data tables in the preview need the CSS in the example, or they render with the browser default.
A readable scores table
Put the thing being compared in the first column. Keep numbers in their own columns so they line up. Use th for labels, not for every bold cell. Add a caption that would still make sense if someone heard it without seeing the grid.
| Student | Quiz | Lab | Total |
|---|---|---|---|
| Ada | 18 | 20 | 38 |
| Linus | 15 | 19 | 34 |
| Grace | 20 | 20 | 40 |
That is the same data as the examples above. Next you will group items that are not a grid: lists.
Worked examples
The short listings above show the tag in isolation. These pages use the same markup on documents you would actually publish: a lab report, a clinic form, a timetable, a weather card.
HTML does not calculate. It names the pieces so a browser, a screen reader, and a search engine can tell a heading from a paragraph. The numbers below are classroom values — the same Ohm, pH, and pulse figures as the C track — now sitting in real page structure.
Preview them in the HTML editor at /html/try. Change a heading or a number and watch the page, not a print log.
Chemistry
A titration table
Tables are for data that has rows and columns, not for laying out a whole site. th is a header cell. td is a data cell. caption names the table.
scope="col" on a column header tells assistive tech which way the header reads. Two titres 24.8 mL and 25.1 mL are a real lab sheet, not a layout trick.
Example
<table>
<caption>HCl vs NaOH titres</caption>
<tr>
<th scope="col">Run</th>
<th scope="col">Volume / mL</th>
</tr>
<tr><td>1</td><td>24.8</td></tr>
<tr><td>2</td><td>25.1</td></tr>
</table>Statistics
Class marks
Five marks in a column is a dataset. The mean 76.8 is not in the table; you would compute it in a script. HTML only records the scores.
mean = (Σ xᵢ) / n
Example
<table>
<caption>Physics test / 100</caption>
<tr><th scope="col">Student</th><th scope="col">Mark</th></tr>
<tr><td>Ada</td><td>72</td></tr>
<tr><td>Ben</td><td>81</td></tr>
<tr><td>Cara</td><td>64</td></tr>
</table>