Skip to main content
📄 HTML & the platform·Module A4 · Lesson 1
TaskBuild a quarterly revenue table. <caption>Quarterly revenue, 2025</caption>, <thead><tr><th scope='col'>Quarter</th><th scope='col'>Revenue</th></tr></thead>, <tbody> with two rows: Q1/$120K and Q2/$180K. Each Quarter cell is a <th scope='row'>.

Tables: <caption>, <thead>, <tbody>, <th scope>

100 XP8 min
Theory

Tables are STILL the right tool for tabular data

For 20 years we've been told "tables are for data only, never layout." Both halves are true: don't use <table> to lay out a page. But when you DO have tabular data — a price chart, a leaderboard, an invoice — a <table> is correct and irreplaceable. Screen readers have keyboard shortcuts to navigate cells by row/column; CSS grid does not.

<table>
  <caption>Quarterly revenue, 2025</caption>
  <thead>
    <tr>
      <th scope="col">Quarter</th>
      <th scope="col">Revenue</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th scope="row">Q1</th>
      <td>$120K</td>
    </tr>
    <tr>
      <th scope="row">Q2</th>
      <td>$180K</td>
    </tr>
  </tbody>
</table>

What each tag does

  • `<caption>` — the table's title (rendered above by default). Screen readers announce it before the table content. Always include it; without one the user has no idea what the table is about.
  • `<thead>` / `<tbody>` — semantic grouping. Screen readers can "skip to data" past the header row.
  • `<th scope="col">` — this cell is a header for the column below it. Screen readers will associate every cell in that column with this header.
  • `<th scope="row">` — this cell is a header for the row to its right. Often the leftmost cell of each body row.
  • `<td>` — regular data cell.

Without scope, screen readers guess

A blind user reading a price chart cell-by-cell hears "$120K" with no context. With scope="col" and scope="row" properly set, they hear "Q1, Revenue, $120K." That's the difference.

🔒

Sign up to start coding

Theory is open to everyone. The interactive editor, live preview, and check are unlocked with a 7-day free trial — card required, cancel anytime.

Sign up — free trial →

First 15 lessons in each track are free. No card needed for those.

PreviousNext lesson →

Get one Python or web tip a day — by email

Short, hand-written, no spam. Unsubscribe in one click.