Course topics

By WebNest Studio Engineering Team

HTML Tutorial

HTML Tables

HTML tables are built for presenting tabular data — information that naturally has rows and columns, like a pricing comparison or a schedule. Tables have a well-defined internal structure with dedicated elements for headers, body rows, and (optionally) footers, and understanding that structure is what separates an accessible, well-formed table from a fragile pile of nested divs pretending to be one.

Why it matters

Prices, timetables, comparison charts and reports are tabular data, and a properly built table lets a screen reader say which row and column a cell belongs to. Tables were once misused for page layout; knowing why that is wrong, and how to mark up headers correctly, is a standard interview topic.

Core Table Elements

A table starts with <table>, which typically contains three sections: <thead> for the header row(s), <tbody> for the main data rows, and optionally <tfoot> for summary rows like totals. Each row is a <tr> (table row), and each row contains cells: <th> for header cells (bold and centered by default, and semantically marked as headers) and <td> for standard data cells.

  • <thead> — wraps the header row(s), containing <th> cells.
  • <tbody> — wraps the main data rows, containing <td> cells.
  • <tfoot> — optional footer rows, often used for totals or summaries.
  • scope="col" or scope="row" on <th> tells assistive technology which cells a header applies to.

Why Tables Should Not Be Used for Page Layout

In the early 2000s, developers commonly used tables to lay out entire web pages (headers, sidebars, columns) because CSS layout tools were immature. This is now considered bad practice: table-based layouts are inaccessible (screen readers announce layout tables as data tables, confusing users with irrelevant row/column announcements), inflexible for responsive design, and mix presentation with structure. Modern layout should always use CSS (Flexbox, Grid) instead, reserving <table> strictly for genuinely tabular data.

Example

A properly structured data table with accessible header scope

HTML
<table>
  <thead>
    <tr>
      <th scope="col">Plan</th>
      <th scope="col">Price</th>
      <th scope="col">Storage</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Basic</td>
      <td>$5/mo</td>
      <td>10 GB</td>
    </tr>
    <tr>
      <td>Pro</td>
      <td>$15/mo</td>
      <td>100 GB</td>
    </tr>
  </tbody>
</table>
Output
Renders a data table with a bold header row (Plan, Price, Storage) and two data rows beneath it; screen readers announce each cell's associated column header when navigating.

Common Mistakes

  • Using <table> elements to build page layout grids instead of CSS Flexbox or Grid.
  • Omitting <th> and using only <td> for header rows, losing semantic meaning and accessibility.
  • Forgetting the scope attribute on header cells in complex tables, making them harder for screen readers to associate with data cells.
  • Nesting a whole table inside a single <td> to fake multi-level layouts instead of using proper nested tables or CSS.

Exercise

Build a table with the caption Course sizes, a header row with the columns Course and Lessons, and two data rows: HTML with 18, and Python with 121. Mark the header cells as column headers.

Expected result: a table with a caption, one header row and two body rows.

HTML · starter code
<table>
  <!-- TODO: caption -->
  <!-- TODO: thead with the two column headers -->
  <!-- TODO: tbody with the two rows -->
</table>
Show hints
  • Header cells are th, and scope="col" says the header applies to its column.
  • The header row goes in thead and the data rows in tbody.
Show solution
HTML · solution
<table>
  <caption>Course sizes</caption>
  <thead>
    <tr>
      <th scope="col">Course</th>
      <th scope="col">Lessons</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>HTML</td>
      <td>18</td>
    </tr>
    <tr>
      <td>Python</td>
      <td>121</td>
    </tr>
  </tbody>
</table>

Quick quiz

1. What is the difference between th and td?

  • A. There is none
  • B. th is a header cell that labels a row or column; td is a data cell
  • C. td is bold
  • D. th can only be used in the first row
Show answer

B. Screen readers announce the matching header when a data cell is read.

2. Which attribute makes one cell span two columns?

  • A. rowspan="2"
  • B. colspan="2"
  • C. span="2"
  • D. width="2"
Show answer

B. rowspan makes a cell span several rows.

3. Why should tables not be used to lay out a page?

  • A. They cannot contain images
  • B. They are no longer supported
  • C. Screen readers announce them as data tables, the markup is rigid, and CSS does layout better
  • D. They are slower than divs to download
Show answer

C. Layout belongs to CSS Flexbox and Grid; tables are for tabular data.

Interview questions

How do you make a data table accessible?

Show answer

Give it a caption that says what the table contains. Mark header cells with th and add scope="col" or scope="row" so each header is tied to its column or row. Group rows with thead, tbody and tfoot. Keep the structure simple, avoiding merged cells where possible, and never use a table for layout.

What are thead, tbody and tfoot for?

Show answer

They group the rows of a table into a header section, the body and a footer section, such as totals. They add meaning for assistive technology, give CSS and JavaScript convenient hooks, and allow a browser to repeat the header and footer on each page when a long table is printed. A table can have several tbody elements to group related rows.

Key Points to Remember

  • Tables are for tabular data, structured as thead/tbody/tfoot containing tr rows of th/td cells.
  • th represents a header cell; td represents a standard data cell.
  • scope="col"/"row" improves accessibility by associating data cells with their headers.
  • Never use tables for general page layout — use CSS Flexbox or Grid instead.

Practice in the playground

Write and run your own code for this topic, or start from the exercise or an example. Shows a live preview of your HTML, CSS and JavaScript. Your code for each topic is kept in this browser.

Run the examples

Change an input, predict the result, then compare it with the output. Explain why the result changes.

WebNest Studio

Written by

WebNest Studio Engineering Team

Practical lessons from developers working with Java, Python, React, databases and production systems.

Led by Vansh Duggal, Founder, WebNest Studio · Full-stack & software engineering