Skip to main content

HTML Tables

Think about a train timetable, a school report card, a price list, or a sports league table. What do they have in common? The information has two directions. You read across to follow one item, and you read down to compare many items. A list cannot do that. A paragraph definitely cannot.

For data that lives in rows and columns, HTML has the table. Tables are one of the most powerful (and most misused) parts of HTML. Used well, they make complex data easy to scan and easy for assistive technology to read. Used badly, they create confusing, broken pages. In this section, you will learn to build tables that are clear, well-structured, and friendly to every reader and every screen size.


What You Will Learn​

In this section, you will be able to:

  • Build a table from <table>, <tr>, <th>, and <td>
  • Understand rows and cells, and how they form columns
  • Mark up heading cells correctly with <th> and scope
  • Add a caption that names the table
  • Group content into <thead>, <tbody>, and <tfoot>
  • Merge cells with colspan and rowspan
  • Style whole columns with <colgroup> and <col>
  • Make tables look good with CSS
  • Make wide tables work on small screens with responsive techniques
  • Make tables accessible to screen reader users
Prerequisites

You should know what elements and attributes are, and be comfortable with basic text elements. If lists are new to you, review the Lists section first. It helps to compare the two.

Your First Table​

Here is a small table with a header row and two rows of data.

index.html
<table>
<tr>
<th>Language</th>
<th>Used for</th>
</tr>
<tr>
<td>HTML</td>
<td>Structure</td>
</tr>
<tr>
<td>CSS</td>
<td>Style</td>
</tr>
</table>

The demo adds borders and a header background with CSS. By itself, a table has no borders at all, only the data laid out in aligned columns.

The Anatomy of a Table​

A table is built from four main pieces. Learn these four, and you can build most tables.

ElementNameJob
<table>TableThe container for everything
<tr>Table RowOne horizontal row
<th>Table Header cellA cell that labels a column or row. Bold and centered by default
<td>Table Data cellA cell that holds data

There is no "column" element at the core of a table. Columns appear on their own when rows stack up: the first cell of every row forms column 1, the second cell forms column 2, and so on.

         column 1     column 2
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
row 1 β”‚ <th> β”‚ <th> β”‚ ← header row
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
row 2 β”‚ <td> β”‚ <td> β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
row 3 β”‚ <td> β”‚ <td> β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
Think in rows

In HTML, you describe a table row by row, from top to bottom, and each row cell by cell, from left to right. Columns come for free.

The Full Set of Table Elements​

Beyond the four basics, HTML has elements that give a table more structure and meaning. You will meet each one in its own lesson.

ElementPurposeLesson
<caption>A title for the tableCaption
<thead>Groups the header rowsThead, Tbody, Tfoot
<tbody>Groups the main data rowsThead, Tbody, Tfoot
<tfoot>Groups the footer rows, such as totalsThead, Tbody, Tfoot
<colgroup> and <col>Describe columns, so you can style themColgroup and Col

Here is a fuller table that uses most of them.

index.html
<table>
<caption>Monthly sign-ups</caption>
<thead>
<tr>
<th scope="col">Month</th>
<th scope="col">Sign-ups</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">January</th>
<td>120</td>
</tr>
<tr>
<th scope="row">February</th>
<td>180</td>
</tr>
</tbody>
<tfoot>
<tr>
<th scope="row">Total</th>
<td>300</td>
</tr>
</tfoot>
</table>

Do not worry about every detail now. Each piece has its own lesson.

When Should You Use a Table?​

Use a table when your content is data with relationships in two directions.

Good useWhy it works
Schedules and timetablesTime runs one way, places or events the other
Price and plan comparisonsFeatures down the side, plans across the top
Scores and statisticsEach row is one team or person, each column a measure
Specifications compared across productsSame properties for many items
CalendarsDays across, weeks down

A Simple Test​

Does the information make sense as a grid, where each cell relates to both its row and its column?

If yes, use a table. If not, choose another tool:

If your content is...Use instead
A single group of itemsA list
One item's properties (name, size, color)A description list
The visual layout of a pageCSS (Flexbox or Grid)
Text with columnsCSS columns

Tables Are for Data, Not for Layout​

In the early years of the web, there was no good way to place things side by side, so developers used tables to build whole page layouts: one cell for the logo, one for the menu, one for the content. It worked, but it caused real problems.

  • Screen readers announce "table, 3 columns, 5 rows" and try to read a page as data when it is not.
  • Small screens cannot rearrange a table layout, so pages broke on phones.
  • Maintenance was painful, because design and content were tangled together.

Today, CSS Flexbox and Grid handle layout far better. Keep tables for data.

Do not use tables for layout

If you are tempted to use a table to place two things side by side, use CSS Grid or Flexbox instead. A table should always mean "this is data in a grid."

Your Learning Path​

Follow the lessons in order. Each one builds on the one before.

Two bonus lessons

This section adds two lessons that were not in the original plan: Colgroup and Col (colgroup-and-col.mdx) and Styling Tables (table-styling.mdx). Column groups are part of the table model that every complete table course should cover, and tables look unfinished without CSS, so each gets its own page.

What Makes a Good Table?​

A quick checklist you will understand fully by the end of this section.

  1. It holds real data, not page layout.
  2. It has a caption that says what the table is.
  3. Its headers use <th>, with scope so every cell knows its labels.
  4. It uses <thead>, <tbody>, and <tfoot> when the table has meaningful sections.
  5. It is simple. Merged cells are used sparingly.
  6. It is styled with CSS, not with old HTML attributes like border and bgcolor.
  7. It works on small screens, without hiding data.
  8. It is accessible, so people using screen readers can understand it.

Common Beginner Mistakes​

MistakeWhat goes wrongWhere you will fix it
Using tables for page layoutPoor accessibility and broken mobile pagesThis page
Using <td> for headers and bolding them by handScreen readers do not know they are headersTable Headings
No captionUsers do not know what the table is aboutCaption
Missing or extra cells in a rowThe table looks broken and misalignedTable Rows and Cells
Overusing colspan and rowspanComplex tables that are hard to navigateColspan and Rowspan
Using old attributes like border and cellpaddingObsolete HTMLStyling Tables
A wide table that breaks the page on phonesSideways scrolling and cut-off dataResponsive Tables
No accessible structureScreen reader users hear a pile of numbersTable Accessibility

Tables for a Global Audience​

Data travels across borders, but how we write it does not. Keep these habits in mind.

  • State units. "Weight (kg)" in the header is better than repeating "kg" in every cell.
  • Be careful with number formats. Some regions write 1,234.56, others 1.234,56. Use clear labels, and consider the lang attribute.
  • Be careful with dates. "03/04/2026" means March 4 in one country and April 3 in another. Write "4 March 2026," or use <time datetime="2026-03-04">.
  • Right-to-left languages such as Arabic and Hebrew flip the column order when the page dir is set to rtl. Use logical CSS properties and test.
  • Do not rely on color alone to show up or down trends. Add a symbol or word.

Quick Recap​

Test yourself. Click a question to reveal the answer.

1. Which four elements make up the core of a table?

<table> (the container), <tr> (a row), <th> (a header cell), and <td> (a data cell).

2. How are columns created in HTML?

They are not declared directly. Cells stacked at the same position in each row form a column.

3. When is a table the right choice?

When the content is data with relationships in both directions: each cell relates to its row and its column. Schedules, comparisons, and statistics are good examples.

4. Why should you not use tables for page layout?

Screen readers treat them as data, they break on small screens, and they mix design with content. Use CSS Grid or Flexbox for layout.

5. Name three elements that add structure beyond the basics.

<caption>, <thead>, <tbody>, <tfoot>, <colgroup>, and <col>. Any three are correct.

Key Takeaways​

  • A table presents data in rows and columns, built with <table>, <tr>, <th>, and <td>.
  • You write rows and cells. Columns appear automatically.
  • Add meaning with <caption>, <thead>, <tbody>, <tfoot>, and scope.
  • Use tables for data, never for layout. Use lists or description lists when the data is not a grid.
  • Style with CSS, make tables work on small screens, and make them accessible to everyone.
  • Write units, dates, and numbers clearly, so your data makes sense around the world.

Ready to begin? Start with Table Basics.