HTML Lesson 12 – Tables in HTML | Dataplexa
B-TAGS/SYNTAX

Tables in HTML

Master HTML tables to organize Alex's portfolio data into rows and columns with proper structure.

Tables organize information into rows and columns — like a spreadsheet. You see them everywhere: sports scores on ESPN, price comparisons on Amazon, or contact lists in your phone. HTML gives us specific tags to build these data grids properly. Think of a table like a filing cabinet. Each drawer is a row, and each section inside is a column. The browser reads your HTML table structure and renders it as a visual grid that users can scan quickly.

Table Tag Anatomy

Every HTML table uses several tags working together. Here's how they connect:
<table> content </table>
Opening tagTable contentClosing tag
The table tag wraps everything. But tables need more tags inside to create the actual structure. Let's build Alex's project list step by step.

Basic Table Structure

Tables have three main parts: the table wrapper, table rows, and table cells. Each row contains cells that line up to form columns.
<!-- Alex wants to display his projects in a table format -->
<table>
  <!-- First row contains project names -->
  <tr>
    <td>Weather App</td>
    <td>Todo List</td>
  </tr>
  <!-- Second row shows the technologies used -->
  <tr>
    <td>JavaScript</td>
    <td>React</td>
  </tr>
</table>
localhost/index.html

What just happened?

The browser created a 2×2 grid automatically. tr means table row, and td means table data cell. Try adding another tr with two td elements for a third row.

That table works, but it's hard to read. The tr tag creates each horizontal row. The td tag creates each cell within that row. Browsers align cells automatically to form columns.

Adding Table Headers

Most tables need headers to explain what each column represents. HTML has a special tag for this: th stands for table header.
<!-- Alex adds headers to make his project table clearer -->
<table>
  <!-- Header row uses th instead of td -->
  <tr>
    <th>Project Name</th>
    <th>Technology</th>
    <th>Status</th>
  </tr>
  <!-- Data rows use regular td tags -->
  <tr>
    <td>Weather App</td>
    <td>JavaScript</td>
    <td>Complete</td>
  </tr>
  <tr>
    <td>Todo List</td>
    <td>React</td>
    <td>In Progress</td>
  </tr>
</table>
localhost/index.html

What just happened?

Headers appear bold and centered by default. The table now has clear column labels that make the data easier to understand. Try changing one th to td to see the difference.

Much better! The th tags automatically make text bold and center it. Screen readers also use these headers to help visually impaired users navigate table data.

Table Structure Tags

Large tables get messy fast. HTML provides three container tags to organize table sections: thead, tbody, and tfoot. Think of them as labeled drawers in your filing cabinet.
<!-- Alex organizes his project table with proper sections -->
<table>
  <!-- Table head contains column headers -->
  <thead>
    <tr>
      <th>Project</th>
      <th>Hours</th>
      <th>Rate</th>
    </tr>
  </thead>
  <!-- Table body contains main data -->
  <tbody>
    <tr>
      <td>Website Redesign</td>
      <td>40</td>
      <td>$50</td>
    </tr>
    <tr>
      <td>Mobile App</td>
      <td>60</td>
      <td>$75</td>
    </tr>
  </tbody>
  <!-- Table foot contains summary info -->
  <tfoot>
    <tr>
      <td>Total</td>
      <td>100</td>
      <td>$6,250</td>
    </tr>
  </tfoot>
</table>
localhost/index.html

What just happened?

The browser displays all sections in order: header, body, footer. Even if you put tfoot before tbody in your HTML, it still renders at the bottom. Try switching their order in the code.

These structural tags don't change the visual appearance by default. But they make your HTML more organized and give CSS better hooks for styling. Many developers skip them for simple tables, but they're essential for complex data.

Spanning Cells

Sometimes you need a cell to stretch across multiple columns or rows. The colspan and rowspan attributes handle this. It's like merging cells in Excel.

Column Spanning

Use colspan to make a cell stretch across multiple columns. The number tells the browser how many columns to cover.
<!-- Alex creates a project timeline with merged headers -->
<table>
  <tr>
    <!-- This header spans across 3 columns -->
    <th colspan="3">Project Timeline - Q1 2024</th>
  </tr>
  <tr>
    <th>January</th>
    <th>February</th>
    <th>March</th>
  </tr>
  <tr>
    <td>Planning</td>
    <td>Development</td>
    <td>Testing</td>
  </tr>
</table>
localhost/index.html

What just happened?

The first header cell stretched across all three columns, creating a title row. The browser automatically calculated the width. Try changing colspan="3" to colspan="2" to see what breaks.

Row Spanning

Use rowspan to make a cell stretch down across multiple rows. This creates vertical merged cells.
<!-- Alex shows project categories with grouped rows -->
<table>
  <tr>
    <th>Category</th>
    <th>Project Name</th>
    <th>Status</th>
  </tr>
  <tr>
    <!-- This cell spans down 2 rows -->
    <td rowspan="2">Frontend</td>
    <td>Portfolio Site</td>
    <td>Complete</td>
  </tr>
  <tr>
    <!-- No category cell here - it's covered by rowspan above -->
    <td>React Dashboard</td>
    <td>In Progress</td>
  </tr>
  <tr>
    <td>Backend</td>
    <td>API Server</td>
    <td>Planning</td>
  </tr>
</table>
localhost/index.html

What just happened?

The "Frontend" cell stretched down to cover two rows, grouping related projects. Notice the second row only has two cells — the browser knows the first column is already occupied. Try adding a cell to that row and see what happens.

Common Mistake

When using rowspan, don't add cells to the rows that are "covered" by the spanning cell. If you add too many td elements, your table layout will break and cells will wrap to new lines.

Table Captions and Accessibility

The caption tag adds a title to your table. It appears above the table and helps screen readers understand what the data represents. Always put it right after the opening table tag.
<!-- Alex adds a descriptive caption to his skills table -->
<table>
  <!-- Caption must be the first element inside table -->
  <caption>Alex's Programming Skills Progress - 2024</caption>
  <thead>
    <tr>
      <th>Skill</th>
      <th>Experience</th>
      <th>Confidence</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>HTML</td>
      <td>2 years</td>
      <td>High</td>
    </tr>
    <tr>
      <td>CSS</td>
      <td>1.5 years</td>
      <td>Medium</td>
    </tr>
  </tbody>
</table>
localhost/index.html

What just happened?

The caption appears centered above the table by default. Screen readers announce this text first, giving users context about the data they're about to hear. Try moving the caption after tbody — it still renders at the top.

Pro tip: Complex tables can also use scope attributes on header cells to specify whether they apply to a column or row. Add scope="col" to column headers and scope="row" to row headers for better accessibility.

Tables are powerful tools for organizing data, but they require careful planning. Start with the basic structure, add headers for clarity, and use spanning attributes sparingly. Always test your tables by tabbing through them with a keyboard to ensure they're accessible. When you're building Alex's portfolio, tables work great for project lists, skill matrices, or client testimonials with ratings. But avoid using tables for page layout — that's what CSS is for. Tables are for data, not design.

Quiz

Alex wants to create column headers in his project table. Which tag should he use?

Alex needs a cell to stretch down across 3 rows in his table. What attribute should he add to the td tag?

Where should Alex place the caption tag in his table structure?

Forms Overview

Build interactive contact forms, search boxes, and user input elements to make Alex's portfolio engaging and functional.