HTML Tutorial
HTML Project: Weekly Timetable
A weekly class timetable as a table with captions, headers, and a highlighted current slot.
What you will build
A weekday class grid for Year 10 science. Columns run Monday to Friday. Four time rows fill the body. One cell is the current slot, marked with a class so CSS can highlight it.
This is tabular data. Use a real table with a caption, a thead, and header cells that declare scope. Do not draw the week with nesteddivs unless you are building a different project.
Preview the grid in /html/try with Try it in HTML. Stretch the pane. The table should remain a table, not a squeezed paragraph.
Tags you will use
| Tag | Job on this page |
|---|---|
table | The week grid |
caption | Names the table for everyone |
thead / tbody | Day headers versus time rows |
th with scope | Column days and row times |
td | The class in that slot |
Build in slices
Caption and header row first. Five day columns plus a blank corner for the time labels.
Example
<table>
<caption>Year 10 science, week of 9 March</caption>
<thead>
<tr>
<th scope="col"><span class="visually-hidden">Time</span></th>
<th scope="col">Mon</th>
<th scope="col">Tue</th>
<th scope="col">Wed</th>
<th scope="col">Thu</th>
<th scope="col">Fri</th>
</tr>
</thead>
</table>Then one body row. The first cell is a row header with scope="row". Mark the current lesson with a class name you will style later.
Example
<tr>
<th scope="row">09:00</th>
<td>Biology</td>
<td class="current">Chemistry</td>
<td>Physics</td>
<td>Biology</td>
<td>Lab write-up</td>
</tr>Highlight with a class on the cell, not with a screenshot overlay. If you print the page, the word Chemistry must still be in the table. Check that in /html/try.
Complete document
Four time rows, Monday to Friday, one current cell. Captions and scopes are in the markup. CSS only paints the highlight.
Example
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Year 10 science timetable</title>
<style>
body {
margin: 0;
background: #f8fafc;
color: #0f172a;
font-family: "Segoe UI", sans-serif;
}
main { max-width: 52rem; margin: 0 auto; padding: 1.3rem; overflow-x: auto; }
table {
width: 100%;
min-width: 32rem;
border-collapse: collapse;
background: #fff;
}
caption {
text-align: left;
font-weight: 700;
margin-bottom: 0.6rem;
font-size: 1.1rem;
}
th, td {
border: 1px solid #cbd5e1;
padding: 0.55rem 0.45rem;
text-align: left;
}
thead th { background: #e2e8f0; }
th[scope="row"] {
white-space: nowrap;
background: #f1f5f9;
font-variant-numeric: tabular-nums;
}
.current {
background: #fde68a;
font-weight: 700;
}
.visually-hidden {
position: absolute;
width: 1px;
height: 1px;
overflow: hidden;
clip: rect(0 0 0 0);
}
p.note { color: #475569; font-size: 0.9rem; }
</style>
</head>
<body>
<main>
<table>
<caption>Year 10 science, week of 9 March</caption>
<thead>
<tr>
<th scope="col"><span class="visually-hidden">Time</span></th>
<th scope="col">Mon</th>
<th scope="col">Tue</th>
<th scope="col">Wed</th>
<th scope="col">Thu</th>
<th scope="col">Fri</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">09:00</th>
<td>Biology</td>
<td class="current">Chemistry</td>
<td>Physics</td>
<td>Biology</td>
<td>Lab write-up</td>
</tr>
<tr>
<th scope="row">10:15</th>
<td>Chemistry</td>
<td>Physics</td>
<td>Biology</td>
<td>Lab</td>
<td>Chemistry</td>
</tr>
<tr>
<th scope="row">11:30</th>
<td>Physics</td>
<td>Biology</td>
<td>Chemistry</td>
<td>Physics</td>
<td>Revision</td>
</tr>
<tr>
<th scope="row">13:30</th>
<td>Lab</td>
<td>Lab</td>
<td>Field sketch</td>
<td>Chemistry</td>
<td>Physics clinic</td>
</tr>
</tbody>
</table>
<p class="note">The gold cell is the current lesson.</p>
</main>
</body>
</html>A second complete timetable
Same grid for a community workshop week. Move the current class to a different cell so you can see the highlight travel.
Example
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Workshop week timetable</title>
<style>
body { margin: 0; background: #111827; color: #f9fafb; font-family: Georgia, serif; }
main { max-width: 50rem; margin: 0 auto; padding: 1.2rem; overflow-x: auto; }
table { width: 100%; min-width: 32rem; border-collapse: collapse; }
caption { text-align: left; margin-bottom: 0.5rem; }
th, td { border: 1px solid #4b5563; padding: 0.45rem; }
thead th, th[scope="row"] { background: #1f2937; }
.current { background: #065f46; }
</style>
</head>
<body>
<main>
<table>
<caption>Community workshop, week of 4 May</caption>
<thead>
<tr>
<th scope="col">Time</th>
<th scope="col">Mon</th>
<th scope="col">Tue</th>
<th scope="col">Wed</th>
<th scope="col">Thu</th>
<th scope="col">Fri</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">09:00</th>
<td>Joinery</td>
<td>Print</td>
<td>Clay</td>
<td>Joinery</td>
<td>Print</td>
</tr>
<tr>
<th scope="row">11:00</th>
<td>Print</td>
<td class="current">Clay</td>
<td>Joinery</td>
<td>Clay</td>
<td>Repair clinic</td>
</tr>
<tr>
<th scope="row">13:30</th>
<td>Clay</td>
<td>Joinery</td>
<td>Print</td>
<td>Print</td>
<td>Open studio</td>
</tr>
<tr>
<th scope="row">15:30</th>
<td>Open studio</td>
<td>Open studio</td>
<td>Open studio</td>
<td>Open studio</td>
<td>Clear-down</td>
</tr>
</tbody>
</table>
</main>
</body>
</html>Common mistakes
- Day names in the first row as
td. Days are headers. Useth. - No
scope. A square grid is ambiguous when a screen reader moves cell by cell. - Highlighting with only a border on a wrapper
divaround the table. Mark the cell. - Merging cells for lunch until the four time rows disappear. Keep four data rows for this project.
- A caption after the table. Put
captionfirst, inside the table.
Practice tasks
- Rewrite every class name for a different subject week. Keep Monday to Friday and four time rows.
- Move the
currentclass to Friday’s last slot. Confirm only one cell is highlighted. - Add a sentence under the table that explains the highlight. Preview at /html/try.