📊 Module 1, Lecture 7: HTML Tables in Detail
Welcome to the wonderful world of HTML Tables! If you've ever used a spreadsheet (like Excel or Google Sheets), you already know what a table is—rows and columns of data. In HTML, tables let us display structured data in a grid format. Think of a school timetable, a price list, or a comparison chart.
🧠 Historical Context: In the 1990s, tables were used to layout entire webpages (like a grid for design). Today, we use CSS for layout (Flexbox & Grid), and we use tables only for tabular data—like spreadsheets, reports, and comparison charts. This is the modern, semantic way!
🧬 1. The Anatomy of an HTML Table
Before we dive into code, let's understand the basic building blocks of any table.
📦 The Basic Tags
<table>– The container for the entire table.<tr>– Table Row (horizontal line).<td>– Table Data (a single cell).<th>– Table Header (bold, centered cell for labels).
🏗️ Visual Structure
┌─────────────────┐ │ <table> │ │ ┌─────────────┐│ │ │ <tr> ││ ← Row 1 │ │ <th> </th> ││ ← Header cell │ │ <td> </td> ││ ← Data cell │ │ </tr> ││ │ └─────────────┘│ │ ┌─────────────┐│ │ │ <tr> ││ ← Row 2 │ │ <td> </td> ││ │ │ <td> </td> ││ │ │ </tr> ││ │ └─────────────┘│ │ </table> │ └─────────────────┘
✅ Golden Rule: Every row (<tr>) must have the same number of cells (<td> or <th>), unless you use colspan or rowspan (which we'll cover later).
📝 Your First Table: A Simple Student List
<table border="1">
<!-- Row 1: Headers -->
<tr>
<th>Name</th>
<th>Age</th>
<th>Grade</th>
</tr>
<!-- Row 2: Data -->
<tr>
<td>Alice</td>
<td>25</td>
<td>A</td>
</tr>
<!-- Row 3: Data -->
<tr>
<td>Bob</td>
<td>22</td>
<td>B+</td>
</tr>
</table>
👀 Result
| Name | Age | Grade |
|---|---|---|
| Alice | 25 | A |
| Bob | 22 | B+ |
✅ <th> cells are bold and centered. <td> cells are regular text.
🧩 2. Semantic Table Sections: <thead>, <tbody>, <tfoot>
Just like a book has a title, chapters, and an index, a well-structured table has distinct parts. These tags do not change the visual appearance (by default), but they are crucial for accessibility, styling, and large datasets.
<thead>– Groups the header rows (column titles).<tbody>– Groups the main body (data rows).<tfoot>– Groups the footer rows (e.g., totals, averages, or summary).
🧠 Pro Tip: The browser will render <tfoot> before <tbody> if you use scrolling, but it will visually appear at the bottom. For screen readers, this structure helps users navigate.
📝 Example: A Sales Report with Total
<table border="1">
<thead>
<tr>
<th>Product</th>
<th>Qty</th>
<th>Price</th>
</tr>
</thead>
<tbody>
<tr>
<td>Laptop</td>
<td>10</td>
<td>$1,200</td>
</tr>
<tr>
<td>Mouse</td>
<td>50</td>
<td>$25</td>
</tr>
</tbody>
<tfoot>
<tr style="font-weight: bold;">
<td>Total</td>
<td>60</td>
<td>$13,250</td>
</tr>
</tfoot>
</table>
👀 Result
| Product | Qty | Price |
|---|---|---|
| Laptop | 10 | $1,200 |
| Mouse | 50 | $25 |
| Total | 60 | $13,250 |
✅ The footer row is logically separate and marked as bold.
🔀 3. Merging Cells: colspan & rowspan
Sometimes you need a cell to stretch across multiple columns (like a title spanning the whole width) or multiple rows (like a label for a group of rows). This is where colspan and rowspan come in.
📐 colspan – Merge Across Columns
Analogy: Merging cells in Excel to make a "header" that spans multiple columns.
<tr>
<th colspan=2>Combined Header</th>
</tr>
✅ The cell takes up the space of 2 columns.
📏 rowspan – Merge Across Rows
Analogy: A vertical label that applies to several rows below it (like a category label).
<td rowspan=3>Category A</td>
✅ The cell stretches down across 3 rows.
📝 Practical Example: A Timetable (Using Both)
<table border="1">
<tr>
<th colspan=6>Weekly Timetable</th>
</tr>
<tr>
<th>Time</th>
<th>Mon</th>
<th>Tue</th>
<th>Wed</th>
<th>Thu</th>
<th>Fri</th>
</tr>
<tr>
<td rowspan=2>Morning</td>
<td>Maths</td>
<td>Science</td>
<td>English</td>
<td>Maths</td>
<td>Science</td>
</tr>
<tr>
<!-- Morning rowspan already used, so no <td> for time -->
<td>Art</td>
<td>Music</td>
<td>PE</td>
<td>Science</td>
<td>Art</td>
</tr>
</table>
👀 Result
| Weekly Timetable | |||||
|---|---|---|---|---|---|
| Time | Mon | Tue | Wed | Thu | Fri |
| Morning | Maths | Science | English | Maths | Science |
| Art | Music | PE | Science | Art | |
✅ colspan="6" merges the title across all columns.
✅ rowspan="2" merges "Morning" down across 2 rows.
⚠️ Important: When you use rowspan or colspan, you must remove the extra cells that are being "covered" so the row count remains correct. If you have a 3-column table and use colspan="2", you only need 2 cells in that row (not 3).
♿ 4. Table Caption & Accessibility
Just like an image needs an alt attribute, a table needs a caption to describe its purpose. This is especially important for screen readers.
<caption> – The Table Title
The <caption> tag is placed directly inside the <table> tag, before any <tr> or <thead>. It visually appears centered above the table (by default).
<table>
<caption>Q4 Sales Report 2026</caption>
<thead>
<tr>
<th>Month</th>
<th>Revenue</th>
</tr>
</thead>
<!-- ... rows ... -->
</table>
👀 Result
| Month | Revenue |
|---|---|
| Oct | $5,000 |
| Nov | $7,200 |
✅ The caption appears above the table as a title.
♿ Accessibility Best Practices
- Always use
<caption>– It's the table's "name tag." - Use
<th>for headers – and use thescopeattribute to clarify if it's a row or column header (e.g.,scope="col"orscope="row"). This helps screen readers announce the header when navigating. - Avoid using tables for layout – Use CSS Grid or Flexbox instead. Tables are for data.
💡 Pro Tip: For complex tables, add id to headers and headers to data cells to create a direct link. But for now, just using <th> and <caption> is a great start!
🎨 5. Styling Tables with CSS (A Quick Look)
In the examples above, we used the old border="1" attribute. But in modern HTML, we use CSS to style tables. Here are the most common CSS properties you'll use:
📦 Common CSS Properties
border-collapse: collapse;– Removes double borders between cells.border: 1px solid #ccc;– Adds a border to the table and cells.padding: 8px;– Adds space inside cells.text-align: left;– Aligns text (default is left for<td>).background-color: #f2f2f2;– Alternating row colors (zebra stripes).width: 100%;– Makes the table fill its container.
📝 CSS-Enhanced Example
<style>
table {
width: 100%;
border-collapse: collapse;
}
th, td {
border: 1px solid #ddd;
padding: 12px;
text-align: left;
}
th {
background-color: #007bff;
color: white;
}
tr:nth-child(even) {
background-color: #f9f9f9;
}
</style>
🧠 Note: We'll dive much deeper into CSS in Module 2. For now, just know that you can make your tables look beautiful with a few lines of CSS!
📊 6. Practical Real-World Examples
Example 1: Student Marksheet (with tfoot for averages)
<table border="1">
<caption>Student Marksheet</caption>
<thead>
<tr>
<th scope="col">Name</th>
<th scope="col">Maths</th>
<th scope="col">Science</th>
<th scope="col">English</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">Alice</th>
<td>90</td>
<td>85</td>
<td>88</td>
</tr>
<tr>
<th scope="row">Bob</th>
<td>70</td>
<td>75</td>
<td>80</td>
</tr>
</tbody>
<tfoot style="font-weight:bold;">
<tr>
<td>Average</td>
<td>80</td>
<td>80</td>
<td>84</td>
</tr>
</tfoot>
</table>
👀 Result
| Name | Maths | Science | English |
|---|---|---|---|
| Alice | 90 | 85 | 88 |
| Bob | 70 | 75 | 80 |
| Average | 80 | 80 | 84 |
✅ Uses scope="row" for row headers and scope="col" for column headers.
Example 2: Product Catalog with Nested Data (Complex)
Here's a more advanced table with a merged category column (rowspan) and a price column.
<table>
<caption>Product Catalog</caption>
<thead>
<tr>
<th>Category</th>
<th>Product</th>
<th>Price</th>
</tr>
</thead>
<tbody>
<tr>
<td rowspan=2 style="font-weight:bold;">Electronics</td>
<td>Laptop</td>
<td>$1,200</td>
</tr>
<tr>
<td>Mouse</td>
<td>$25</td>
</tr>
<tr>
<td rowspan=1 style="font-weight:bold;">Furniture</td>
<td>Chair</td>
<td>$150</td>
</tr>
</tbody>
</table>
👀 Result
| Category | Product | Price |
|---|---|---|
| Electronics | Laptop | $1,200 |
| Mouse | $25 | |
| Furniture | Chair | $150 |
✅ "Electronics" spans 2 rows using rowspan="2".
🎯 Module 1, Lecture 7 Challenge: Build Your Own Timetable
Now it's your turn! Build a complete class schedule for a fictional school. Your table must include:
- A caption ("Spring 2026 Class Schedule").
- A thead with columns: "Time", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday".
- A tbody with at least 3 time slots (e.g., 9:00 AM, 10:00 AM, 11:00 AM).
- Use colspan to merge a "Lunch Break" cell across all 5 weekday columns.
- Use rowspan to merge a "Morning Session" label across the first 2 rows.
- A tfoot that says "Total Hours: 15" (or any summary).
👀 Click to see a sample solution (peek only if stuck!)
<table border="1" style="border-collapse: collapse; width: 100%;">
<caption style="font-weight: bold; font-size: 1.2rem; margin-bottom: 0.5rem;">Spring 2026 Class Schedule</caption>
<thead style="background-color: #007bff; color: white;">
<tr>
<th>Time</th>
<th>Monday</th>
<th>Tuesday</th>
<th>Wednesday</th>
<th>Thursday</th>
<th>Friday</th>
</tr>
</thead>
<tbody>
<!-- Morning Session (rowspan=2) -->
<tr>
<td rowspan=2 style="font-weight: bold; background-color: #f0f0f0;">9:00 AM - 10:30 AM</td>
<td>Maths</td>
<td>Science</td>
<td>English</td>
<td>Maths</td>
<td>Science</td>
</tr>
<tr>
<!-- No time cell here because of rowspan -->
<td>Art</td>
<td>Music</td>
<td>PE</td>
<td>Science</td>
<td>Art</td>
</tr>
<!-- Lunch Break (colspan=6) -->
<tr style="background-color: #fff3cd;">
<td colspan=6 style="text-align: center; font-weight: bold;">🍽️ Lunch Break (12:00 PM - 1:00 PM)</td>
</tr>
<!-- Afternoon Session -->
<tr>
<td rowspan=1 style="font-weight: bold; background-color: #f0f0f0;">1:00 PM - 2:30 PM</td>
<td>History</td>
<td>Geography</td>
<td>History</td>
<td>PE</td>
<td>Geography</td>
</tr>
</tbody>
<tfoot style="font-weight: bold; background-color: #e9ecef;">
<tr>
<td colspan=6 style="text-align: center;">Total Hours: 15 (5 days x 3 hours)</td>
</tr>
</tfoot>
</table>
🎉 You've mastered HTML Tables! Next up: Module 2 – CSS Styling!