HTML Tables: Laying Out Data in Rows and Columns

Tables organize data into rows and columns — price lists, schedules, comparisons. Learn the table, tr, th, and td elements, how to build a clean table, and the one mistake to avoid with tables.

Published July 4, 20266 min readBy ACY Partner Indonesia
HTML tables — the table, tr, th, and td elements
300 × 250Ad Space AvailablePlace your ad here

Some information is just naturally a grid: a price list, a class schedule, a comparison of plans, the stats on a sports page. When your data has rows and columns that line up, an HTML table is the right tool for the job. Tables have a slightly fussier structure than other elements, but once you see how the pieces fit together, they’re completely logical.

This article shows you how to build a table properly, what each element is for, and — importantly — the one big mistake to avoid: using tables for the wrong job.

The pieces of a table

A table is built from a few elements that nest inside one another. Here are the core ones:

  • <table> — wraps the whole thing.
  • <tr> — a table row (one horizontal row).
  • <th> — a table header cell (the bold titles at the top of columns).
  • <td> — a table data cell (a normal cell with content).

The mental model is simple: a table is a stack of rows (<tr>), and each row is a series of cells (<th> for headers, <td> for data). You build a table row by row, left to right.

Building your first table

Let’s make a small table — a list of three programming languages and what they’re for:

<table>
  <tr>
    <th>Language</th>
    <th>Used for</th>
  </tr>
  <tr>
    <td>HTML</td>
    <td>Structure</td>
  </tr>
  <tr>
    <td>CSS</td>
    <td>Styling</td>
  </tr>
  <tr>
    <td>JavaScript</td>
    <td>Behavior</td>
  </tr>
</table>

Read it from the top down and it makes sense:

  • The whole thing is wrapped in <table>.
  • The first <tr> is the header row — its cells are <th>, which browsers render bold and centered by default.
  • Each following <tr> is a data row, with <td> cells holding the actual content.

Every row has the same number of cells (here, two), which is what keeps the columns lined up. That’s the golden rule of tables: each row should have the same number of cells.

th versus td — it's about meaning, not just bold

Use <th> for header cells and <td> for data cells. Yes, <th> looks bold by default, but the real reason to use it is meaning: it tells screen readers “this cell is a heading for the column (or row) below it.” When a screen-reader user moves through the table, the browser can announce the relevant header for each cell, so they don’t lose track of which column they’re in. Using <th> properly makes your table understandable to everyone.

Giving the table structure: thead, tbody, and a caption

For anything bigger than a tiny table, it’s good practice to group the rows into a head and a body, and to give the table a caption. These small additions buy you clarity and accessibility:

<table>
  <caption>Programming languages and their roles</caption>
  <thead>
    <tr>
      <th>Language</th>
      <th>Used for</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>HTML</td>
      <td>Structure</td>
    </tr>
    <tr>
      <td>CSS</td>
      <td>Styling</td>
    </tr>
  </tbody>
</table>

A few new pieces here:

  • <caption> is a title for the whole table. It goes right after the opening <table> tag and describes what the table contains — helpful for everyone, and especially for screen-reader users.
  • <thead> groups the header row(s).
  • <tbody> groups the data rows.

These grouping elements don’t change much visually on their own, but they make the table’s structure explicit, which helps accessibility and makes styling easier later.

Cells that span multiple columns or rows

Sometimes a single cell needs to stretch across more than one column or row. Two attributes handle that:

  • colspan makes a cell span multiple columns.
  • rowspan makes a cell span multiple rows.

For example, a cell that spans two columns:

<table>
  <tr>
    <th colspan="2">Contact Information</th>
  </tr>
  <tr>
    <td>Email</td>
    <td>support@acy-partner.com</td>
  </tr>
</table>

The colspan="2" makes that header cell as wide as the two columns below it. rowspan does the same thing, just vertically. You won’t reach for these often, but they’re a lifesaver when your data genuinely has merged headers or grouped cells.

The big mistake: don’t use tables for page layout

This is the single most important warning in the whole article. Tables are for tabular data — and only for tabular data. Don’t use them to lay out the overall structure of a page.

Years ago, before modern CSS existed, developers misused tables to position everything on a page — header in one cell, sidebar in another, content in a third. It worked visually, but it was a bad idea, and today it’s firmly considered wrong.

Tables are for data, not layout

If you find yourself reaching for a table to put your sidebar next to your main content, or to arrange a page into columns, stop. That’s a job for CSS layout (using tools like Flexbox and Grid), not tables. Using tables for layout makes pages inaccessible — screen readers try to read the “data” and get hopelessly confused — and it makes the page rigid and hard to maintain. The rule is simple: if the content isn’t genuinely a grid of related data, don’t use a table.

So how do you tell whether something is tabular data? Ask yourself: would this make sense as a spreadsheet, with meaningful column headers and rows of related values? A price list, a schedule, a comparison chart — yes. The general layout of your page — no.

A practical example

Let’s finish with a realistic table you might actually build — a simple pricing comparison:

<table>
  <caption>Plan comparison</caption>
  <thead>
    <tr>
      <th>Feature</th>
      <th>Basic</th>
      <th>Pro</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Storage</td>
      <td>10 GB</td>
      <td>100 GB</td>
    </tr>
    <tr>
      <td>Support</td>
      <td>Email</td>
      <td>Email + phone</td>
    </tr>
  </tbody>
</table>

This is exactly what tables are made for: rows and columns of genuinely related data, with clear headers. A reader — sighted or using a screen reader — can scan across a row to compare, or down a column to see every value for one feature. That clarity is the whole point of a table.

Wrapping up

You can now present structured data cleanly:

  • A <table> is built from rows (<tr>) containing header cells (<th>) and data cells (<td>).
  • Keep every row the same number of cells so the columns align.
  • Use <th> for headers — it carries meaning for accessibility, not just bold styling.
  • Add a <caption> and group rows with <thead> and <tbody> for clarity on larger tables.
  • Use colspan and rowspan when a cell needs to merge across columns or rows.
  • Never use tables for page layout — they’re for tabular data only; layout is CSS’s job.

That rounds out the structural HTML elements. You’ve now covered text, links, images, forms, and tables — the building blocks of real pages. In the final stretch of this section, we’ll step up to a more thoughtful way of writing HTML: semantic HTML, where you choose elements that describe the meaning of each part of your page, not just its appearance.

Tags:htmlfrontendtablesbeginner
728 × 90Ad Space AvailablePlace your ad here

Related Articles

See All Articles

You Might Also Like

Frontend best practices overview cover
Frontend / Fundamentals

Frontend Best Practices: An Overview

A friendly map of what good frontend really means — semantic HTML, clean CSS, unobtrusive JavaScript, responsive layouts, performance, and progressive enhancement, with pointers to go deeper.

Sep 20, 20268 min read
A Frontend Developer Roadmap cover with the path HTML to CSS to JavaScript
Frontend / Fundamentals

A Frontend Developer Roadmap: What to Learn, and in What Order

A calm, step-by-step learning path for beginners: HTML, CSS, JavaScript, developer tools, responsive and accessible design, a framework, TypeScript, and deployment, with the reasoning behind each step.

Sep 20, 202611 min read
Title card reading Styling and Interactivity over a dark blue ACY Partner background
Frontend / Fundamentals

How Styling and Interactivity Work

A beginner-friendly look at how CSS turns plain HTML into a designed layout, and how JavaScript adds behavior — the structure, style, behavior mental model for building web pages.

Sep 20, 20269 min read
Three front-end layers combining on one web page
Frontend / Fundamentals

How HTML, CSS, and JavaScript Work Together

A hands-on walkthrough for beginners: build one small button, give it structure with HTML, looks with CSS, and behavior with JavaScript, and watch the three layers cooperate on a real page.

Sep 20, 20268 min read
The Frontend Developer Toolkit cover with editor, browser, and CLI motifs
Frontend / Fundamentals

The Frontend Developer Toolkit

A friendly tour of the everyday tools a frontend developer relies on — code editor, browser and DevTools, terminal, version control, package managers, and a dev server — and what each one is actually for.

Sep 20, 202610 min read
Cover illustration for What Frontend Developers Do
Frontend / Fundamentals

What Frontend Developers Do: A Beginner's Guide to the Role

A clear, beginner-friendly look at what frontend developers actually do every day: turning designs into working interfaces, building reusable UI, and caring about responsiveness, accessibility, and speed.

Sep 20, 202610 min read