HTML Tables
HTML tables allow you to display data in a structured grid of rows and columns — perfect for schedules, comparison charts, pricing tables, sports scores, financial data, and any information that has a natural tabular format. While CSS frameworks have replaced the old practice of using tables for page layout, tables remain the correct and accessible choice for displaying actual data. Understanding how to build proper HTML tables with headers, body, footer, and merged cells is an essential skill for web development.
HTML Tables
Tables display data in a grid of rows and columns. They are one of the oldest HTML elements, and they are still the RIGHT choice for presenting tabular data — data that has natural rows and columns like spreadsheets, schedules, or comparison charts. The basic structure is: <table> contains <tr> (table row), which contains either <th> (table header cell) or <td> (table data cell). For better structure and accessibility, you should group your rows using: • <thead> — Groups the header rows (the row with column titles) • <tbody> — Groups the main data rows • <tfoot> — Groups footer rows (totals, summaries) These grouping tags help screen readers understand the table structure, they allow independent scrolling of the body while keeping headers fixed, and they help with CSS styling. Important: Tables should ONLY be used for tabular data, NOT for page layout. In the early days of the web (1990s-2000s), developers used tables to create page layouts — this practice is now considered obsolete and harmful to accessibility. Use CSS Grid or Flexbox for layouts, and reserve tables for actual data. Accessibility tip: Always include <th> elements with scope='col' (for column headers) or scope='row' (for row headers). This tells screen readers which cells are headers and which direction they apply, making the table navigable for visually impaired users.
Table Tags — Complete Reference
- <table> — Creates the table container. Add border='1' for visible borders (though CSS is preferred for styling).
- <tr> — Table row. Each row contains header cells (<th>) or data cells (<td>).
- <th> — Table header cell. Bold and centered by default. Use in the first row for column titles, or first column for row labels.
- <td> — Table data cell. Regular text, left-aligned by default. Contains the actual data.
- <thead> — Groups header rows. Helps screen readers, enables sticky headers with CSS, and separates structure.
- <tbody> — Groups body/data rows. The main content area of the table.
- <tfoot> — Groups footer rows. Used for totals, averages, or summary data. Browsers may render <tfoot> at the bottom even if coded before <tbody>.
- <caption> — Table title/description. Placed immediately after <table>. Important for accessibility — screen readers announce it before reading the table.
- colspan='N' — Merges N columns into one cell horizontally. Example: <td colspan='3'> spans across 3 columns.
- rowspan='N' — Merges N rows into one cell vertically. Example: <td rowspan='2'> spans 2 rows.
- scope='col' or scope='row' — On <th> elements, tells screen readers the direction the header applies to. Essential for accessible tables.
Table Example
<!DOCTYPE html>
<html>
<body>
<h2>Student Results</h2>
<!-- caption provides an accessible title -->
<table border="1" style="border-collapse:collapse; width:100%">
<caption>Semester 1 Exam Results</caption>
<thead>
<tr>
<th scope="col" style="padding:10px;background:#04AA6D;color:white">Name</th>
<th scope="col" style="padding:10px;background:#04AA6D;color:white">Subject</th>
<th scope="col" style="padding:10px;background:#04AA6D;color:white">Marks</th>
<th scope="col" style="padding:10px;background:#04AA6D;color:white">Grade</th>
</tr>
</thead>
<tbody>
<tr>
<td style="padding:10px">Alice</td>
<td style="padding:10px">Mathematics</td>
<td style="padding:10px">95</td>
<td style="padding:10px">A+</td>
</tr>
<tr>
<td style="padding:10px">Bob</td>
<td style="padding:10px">Science</td>
<td style="padding:10px">88</td>
<td style="padding:10px">A</td>
</tr>
<tr>
<td style="padding:10px">Charlie</td>
<td style="padding:10px">English</td>
<td style="padding:10px">72</td>
<td style="padding:10px">B</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="2" style="padding:10px"><strong>Average</strong></td>
<td style="padding:10px"><strong>85</strong></td>
<td style="padding:10px"><strong>A</strong></td>
</tr>
</tfoot>
</table>
</body>
</html>