🎉
Lesson Complete!
Table structure done! Final table topic — colspan and rowspan.
📊 Phase 4 · Tables & Forms🟡 IntermediateModule 05

Table Structure

⏱ 18 min read📖 4 sections🧩 5-question quiz
Course Progress46% complete
A complete semantic table isn't just rows and cells — it has a head, body, and foot, just like a document. Structural elements like <thead>, <tbody>, and <tfoot> group rows by purpose, enable independent scrolling, and help screen readers navigate complex data tables correctly.

thead, tbody, tfoot

These three sectioning elements divide a table into logical regions:

thead
Column headers — repeats on every printed page
tbody
Main data rows — can be multiple tbody sections
tbody
Second tbody section (optional, for grouping)
tfoot
Summary/totals row — may scroll with body in CSS
HTMLFully structured table
<table>
  <caption>Q3 Sales Report</caption>

  <thead>
    <tr>
      <th scope="col">Product</th>
      <th scope="col">Units Sold</th>
      <th scope="col">Revenue</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <th scope="row">HTML Course</th>
      <td>1,240</td>
      <td>£12,400</td>
    </tr>
    <tr>
      <th scope="row">CSS Course</th>
      <td>980</td>
      <td>£9,800</td>
    </tr>
  </tbody>

  <tfoot>
    <tr>
      <th scope="row">Total</th>
      <td>2,220</td>
      <td>£22,200</td>
    </tr>
  </tfoot>
</table>

The scope Attribute

The scope attribute on <th> tells screen readers whether a header applies to a column, row, or group of columns/rows. It dramatically improves accessibility on complex tables.

scope valueMeaningExample
colHeader for the column below itColumn labels in thead
rowHeader for the row it's inRow label as first cell
colgroupHeader for a group of columnsSpanning grouped header
rowgroupHeader for a group of rowsGroup label spanning rows
scope makes tables screen-reader friendly
Without scope, screen readers must guess which headers apply to which cells. With it, a screen reader can announce "Product: HTML Course, Units Sold: 1,240" — the user always knows the context of each value.

Column Groups

The <colgroup> element (and its children <col>) let you apply styling to entire columns without adding classes to every cell. Place it immediately after the <caption> and before <thead>.

HTML + CSScolgroup and col
<table>
  <caption>Browser Support</caption>

  <!-- style columns without touching every td -->
  <colgroup>
    <col style="width: 40%">  <!-- Feature column -->
    <col style="background: rgba(45,232,192,.05)">  <!-- Chrome -->
    <col>  <!-- Firefox -->
    <col>  <!-- Safari -->
  </colgroup>

  <thead>
    <tr>
      <th scope="col">Feature</th>
      <th scope="col">Chrome</th>
      <th scope="col">Firefox</th>
      <th scope="col">Safari</th>
    </tr>
  </thead>
  <!-- tbody rows ... -->
</table>

Long Table Scrolling

For long data tables on mobile, wrap the table in a container with overflow-x: auto to allow horizontal scrolling without breaking the page layout. This is far better than a table that overflows off-screen.

HTML + CSSResponsive table wrapper
<!-- HTML -->
<div class="table-wrap">
  <table>
    <!-- ... lots of columns -->
  </table>
</div>

/* CSS */
.table-wrap {
  overflow-x: auto;         /* horizontal scroll */
  -webkit-overflow-scrolling: touch;  /* smooth iOS scroll */
  border-radius: 8px;
  border: 1px solid #e2e8f0;
}
🧩 Quick Check — Lesson 16
5 questions · instant feedback
1. Which element wraps the column header row(s) of a table?
2. What does scope="col" on a <th> element tell screen readers?
3. Where should tfoot content appear visually?
4. What is the purpose of <colgroup> and <col>?
5. How do you make a wide table scroll horizontally on mobile?
🏆
Quiz Complete!
Table structure done! Last table topic: colspan & rowspan.
🏆
Lesson 16 Challenge
Code exercise · 15 min
Build a fully structured data table with thead, tbody, and tfoot.

Create a monthly budget table with these columns: Category, Budget, Actual, Difference.

1. Use <caption> with a descriptive title
2. Use <thead> with <th scope="col"> for all column headers
3. Use <tbody> for at least 4 spending categories (Rent, Food, Transport, Entertainment)
4. Use row headers <th scope="row"> for each category name
5. Use <tfoot> for the totals row
6. Wrap in a div.table-wrap with overflow-x: auto
Show hints
  • tfoot can appear in source before tbody — it'll still render at the bottom
  • scope="col" on column headers, scope="row" on row headers
  • The totals row uses th for the label and td for the sums
  • Style thead differently from tbody for visual hierarchy