Mastering HTML Tables: `colspan` & `rowspan`

Go beyond simple grids. Learn to merge cells and build complex, accessible data tables like a professional.

Lesson ProgressStep 1 of 8
0 EXP

Welcome! Let's learn how to build complex tables by merging cells, a key skill for data presentation.

/* Let's build a table! */

Spanning Columns with `colspan`

The colspan attribute is used on a <th> or <td> tag to make a single cell stretch **horizontally** across multiple columns. The value you provide is the number of columns it should occupy.

<tr>
  <th colspan="3">Monthly Report</th>
</tr>
<tr>
  <td>Jan</td>
  <td>Feb</td>
  <td>Mar</td>
</tr>

In this example, the header "Monthly Report" spans all three data columns below it. The first row has only one cell, while the second row has three.

System Check

A table has 4 columns. How would you make a header span all of them?

Advanced Holo-Simulations

0 EXP

Log in to unlock these advanced training modules and test your skills.


Achievements

🏆
Cell Merger

Successfully merge cells using both colspan and rowspan.

🏗️
A11y Advocate

Correctly use the `scope` attribute for table accessibility.

✍️
Structure Architect

Build a table using `<caption>`, `<thead>`, and `<tbody>`.

Mission: Build a Complex Schedule

Create a table with a `caption`, `thead`, and `tbody`. It must include at least one `colspan`, one `rowspan`, and `scope` attributes on all headers (<th>).

A.D.A. Feedback:

> Awaiting input...

Challenge: Order the Table Structure

Drag the elements into the correct semantic order for a structured table. (Note: <tr> content is simplified).

<tr>...</tr>
<table>
</table>
</tbody>
<thead>

Challenge: Complete the Attributes

Fill in the missing attributes to make the table correct.

<th ="2">Header</th>
<td ="2">Data</td>
<th ="col">Col Header</th>

Consult A.D.A.

Unlock with Premium

Community Holo-Net

Peer Project Review

Submit your "Complex Schedule" project for feedback from other Net-Runners.

Beyond the Grid: A Deep Dive into Advanced HTML Tables

In the early days of the web, HTML tables were the primary tool for page layout. While this practice is now obsolete (we use CSS Flexbox and Grid for layout), tables remain the single best way to display tabular data—information that belongs in a grid of rows and columns.

But data isn't always neat. Sometimes, a category needs to span multiple rows, or a main header needs to cover several sub-headers. This is where the `colspan` and `rowspan` attributes become essential.

Anatomy of a Semantic Table

Before merging cells, it's vital to use the correct structure. A semantic table is not just a <table> with <tr> and<td> tags. It has a clear, descriptive structure:

  • <caption>: The title of the table. It should be the *first* child of the<table>` tag and is crucial for accessibility.
  • <thead>: Groups the header content (<tr> containing <th>tags) of the table.
  • <tbody>: Groups the main data content (the body) of the table.
  • <tfoot>: Groups the footer content of the table, such as totals or summaries.
<table>
  <caption>Monthly Expenses</caption>
  <thead>
    <tr>
      <th>Item</th>
      <th>Cost</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Groceries</td>
      <td>$300</td>
    </tr>
  </tbody>
  <tfoot>
    <tr>
      <td>Total</td>
      <td>$300</td>
    </tr>
  </tfoot>
</table>

Spanning Columns with `colspan`

The `colspan` attribute specifies how many **columns** a single cell should span (merge across). It's placed on a <th> or<td> tag.

Imagine a table header for "Full Name" that needs to cover two columns: "First" and "Last".

Code

<thead>
  <tr>
    <th colspan="2">Full Name</th>
    <th>Age</th>
  </tr>
  <tr>
    <th>First</th>
    <th>Last</th>
    <th></th>
  </tr>
</thead>
Full NameAge
FirstLast

The "Gotcha": Notice the first `<tr>` only has two `<th>` elements. The first one (`colspan="2"`) takes up 2 columns, and the second one takes up 1, for a total of 3 columns. The *next* row must then define all 3 columns individually.

Spanning Rows with `rowspan`

Similarly, `rowspan` specifies how many **rows** a cell should span (merge down).

Imagine a "Category" cell that applies to multiple items, like "Fruits".

Code

<tbody>
  <tr>
    <td rowspan="2">Fruits</td>
    <td>Apple</td>
  </tr>
  <tr>
    <td>Banana</td>
  </tr>
</tbody>
FruitsApple
Banana

The "Gotcha": Notice the first `<tr>` has two `<td>` elements. The second `<tr>` only has **one** `<td>` element. This is because the first cell from the row above is still occupying its space. This cell-counting logic is the most common point of failure when building complex tables.

Accessibility is Non-Negotiable: The `scope` Attribute

A sighted user can visually connect a header to its data. A screen reader user cannot. They rely on the `scope` attribute on `<th>` tags to make this connection.

  • scope="col": Use this on a `<th>` that is a header for a **column**.
  • scope="row": Use this on a `<th>` that is a header for a **row**.

When a screen reader navigates to a `<td>` cell, it will read out the cell's content *and* the content of the headers associated with it via the `scope` attribute. Without `scope`, a complex table is just a confusing jumble of data.

Styling Columns with `<colgroup>`

What if you want to make the entire second column of a table yellow? Instead of adding a class to every `<td>` in that column, you can use the `<colgroup>` and `<col>` tags.

Placed directly after the `<caption>`, `<colgroup>` defines a group of one or more columns for styling.

<table>
  <caption>Column Styling</caption>
  <colgroup>
    <col>
    <col style="background-color: #fef9c3;">
    <col>
  </colgroup>
  <thead>
    <tr>
      <th>Item</th>
      <th>Quantity</th>
      <th>Price</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Apple</td>
      <td>10</td>
      <td>$5</td>
    </tr>
  </tbody>
</table>
Key Takeaway: Use colspan and rowspan to accurately represent complex data relationships. Always use semantic tags like <caption>, <thead>,<tbody>, and <tfoot>. And **never** forget the `scope` attribute on headers—it's the most important part of building an accessible, professional-grade table.

Advanced Table Glossary

<table>
The wrapper element for all HTML table content.
<caption>
The title or caption of the table. Must be the first child of<table>. Essential for accessibility.
<thead>
Groups the header row(s) (<tr> containing <th>elements) of the table.
<tbody>
Groups the main body content (data rows) of the table.
<tfoot>
Groups the footer row(s) of the table, typically for summaries or totals.
<tr>
Table Row. Defines a single row of cells in a table.
<th>
Table Header. Defines a header cell. It should always have a `scope` attribute.
<td>
Table Data. Defines a standard data cell.
colspan
An attribute for <th> or <td> that specifies the number of columns the cell should span (merge horizontally).
rowspan
An attribute for <th> or <td> that specifies the number of rows the cell should span (merge vertically).
scope
An attribute for <th> that specifies whether the header is for a column (`scope="col"`) or a row (`scope="row"`). Critical for accessibility.
<colgroup>
An element that groups one or more <col> elements, allowing for styling of entire columns.
<col>
A self-closing tag used within a <colgroup> to define properties for a single column.

Credibility and Trust

About the Author

Author's Avatar

Todotutorial Team

Passionate developers and educators making programming accessible to everyone.

This article was written and reviewed by our team of web development experts, who have years of experience teaching HTML and building robust and accessible web applications.

Verification and Updates

Last reviewed: October 2025.

We strive to keep our content accurate and up-to-date. This tutorial is based on the latest HTML5 specifications and WAI-ARIA accessibility guidelines.

External Resources

Found an error or have a suggestion? Contact us!