HTML Table Header Tag ( <th> ) Explained With Examples

HTML Tutorials · HTML Table Headers Tag · Introduction

HTML Table Headers Tutorial: <th> Tag Usage, Syntax & Best Practices

HTML table headers are defined using the <th> (table header) element, and they are typically placed inside a <thead> section of a table. Headers usually appear bold and centered by default.

This tutorial covers three core header patterns, column headers, row headers, and captioned tables, along with the difference between th and td, the scope attribute for accessibility, styling headers with CSS, colspan and rowspan for grouped headers, and how table structure connects to SEO, plus a live playground further down the page where you can test any header pattern instantly.

HTML table header th tag example - Trulli
HTML table header example
HTML table with header row rendered in a browser - Trulli
Table headers in a browser

Table Header Examples

Three practical ways to use the <th> tag, from a simple header row to row headers and a captioned table, each with its exact code and rendered result.

📋 1. Syntax of Table Headers

ExampleCopy Code
<table border="1">
  <thead>
    <tr>
      <th>Product</th>
      <th>Price</th>
      <th>Quantity</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Laptop</td>
      <td>$1000</td>
      <td>2</td>
    </tr>
    <tr>
      <td>Phone</td>
      <td>$500</td>
      <td>5</td>
    </tr>
  </tbody>
</table>

Rendered Result

ProductPriceQuantity
Laptop$10002
Phone$5005

🧹 2. Column and Row Headers

ExampleCopy Code
<table border="1">
  <tr>
    <th></th>
    <th>Math</th>
    <th>Science</th>
    <th>English</th>
  </tr>
  <tr>
    <th>Pooja</th>
    <td>85</td>
    <td>90</td>
    <td>80</td>
  </tr>
  <tr>
    <th>Ovi</th>
    <td>92</td>
    <td>88</td>
    <td>95</td>
  </tr>
</table>

Rendered Result

MathScienceEnglish
Pooja859080
Ovi928895

Notice that <th> is used twice here: once across the top for column headers (Math, Science, English), and once down the left side for row headers (Pooja, Ovi). Both uses are equally valid, a <th> simply marks whichever cell, row, or column it sits in as a header rather than plain data.

🧹 3. Table Caption (Name)

ExampleCopy Code
<table style="width:100%">
  <caption>Monthly savings in Payment</caption>
  <tr>
    <th>Month</th>
    <th>Savings</th>
  </tr>
  <tr>
    <td>March</td>
    <td>$50</td>
  </tr>
  <tr>
    <td>May</td>
    <td>$30</td>
  </tr>
</table>

Rendered Result

Monthly savings in Payment
MonthSavings
March$50
May$30

🔍 Table Tag Breakdown

Tag Purpose
<table>Defines the table
<tr>Table row
<th>Table header (bold + centered by default)
<td>Table data (cell content)
<caption>Defines a table caption
<colgroup>Specifies a group of one or more columns in a table for formatting
<col>Specifies column properties for each column within a colgroup element
<thead>Groups the header content in a table
<tbody>Groups the body content in a table

Try It Yourself (Copy This Code and Paste. See how it works). Paste any of the three examples above into the live playground below and swap the header text or add a new row to see the change instantly.

</> Try It Yourself (Copy this code and paste. See how it works)

Live Code Preview

th vs td: What Is the Actual Difference?

Both <th> and <td> define a table cell, and visually they can even be made to look identical with enough CSS, but they are not interchangeable, since they carry different meaning underneath that styling.

<th> <td>
Marks a cell as a headerMarks a cell as ordinary data
Bold and centered by defaultNormal weight and left-aligned by default
Announced distinctly by screen readersRead as plain content
Can appear in a header row or as a row labelNever used for headers

Using <td> for something that is genuinely a header, just because you have styled it to look bold yourself, throws away the semantic meaning a screen reader or search engine would otherwise get for free from a real <th> tag.

The scope Attribute for Table Headers

The Column and Row Headers example earlier on this page uses <th> in two different directions, across the top and down the left side, which is exactly the situation the scope attribute was designed for. Adding scope tells assistive technology whether a given header describes its column or its row.

ExampleCopy Code
<table border="1">
  <tr>
    <th></th>
    <th scope="col">Math</th>
    <th scope="col">Science</th>
  </tr>
  <tr>
    <th scope="row">Pooja</th>
    <td>85</td>
    <td>90</td>
  </tr>
</table>
Value Meaning
scope="col"This header describes every cell below it in the same column
scope="row"This header describes every cell beside it in the same row

Without scope, a screen reader can usually still guess a simple table's structure, but on a more complex table, especially one with headers running in both directions like the Pooja/Ovi grades example, scope removes the guesswork entirely and is considered a genuine accessibility best practice rather than an optional extra.

Row Headers vs Column Headers in Practice

The two directions <th> can run, across the top or down the side, suit different kinds of data, and recognizing which one your table needs is worth thinking through before you start writing markup.

Styling Table Headers with CSS

Because <th> is a distinct tag from <td>, it can be styled independently, which is how most real websites give header rows a distinct background color or border rather than relying on the plain bold-and-centered browser default.

ExampleCopy Code
<style>
    th {
        background-color: #2563eb;
        color: white;
        padding: 8px;
        text-align: left;
    }
    td {
        padding: 8px;
        border-bottom: 1px solid #ddd;
    }
</style>

This small stylesheet gives every <th> on the page a blue background with white text, visually separating headers from data far more clearly than the plain default bold-and-centered styling, while leaving <td> cells untouched except for a light bottom border between rows.

Common Mistakes With HTML Table Headers

Practice Exercises: Try Every Header Technique

The fastest way to make table headers feel natural is to build a few variations yourself. Try each of these directly in the live editor above:

  1. Recreate the Syntax of Table Headers example, then add a fourth column with its own header.
  2. Build a table with row headers only, no column headers, labeling three rows of data.
  3. Add scope="col" and scope="row" to the Column and Row Headers example.
  4. Add a <caption> to a table you build from scratch, describing what it shows.
  5. Style your <th> cells with a custom background color, leaving <td> cells with the default styling.

Working through these five exercises covers every header technique discussed in this tutorial, from a simple column header row to a fully accessible, captioned, cross-referenced table.

Real-World Example: A Fully Accessible Data Table

To see column headers, row headers, a caption, and the scope attribute working together the way a real, accessible table should, here is a complete example combining every technique covered on this page:

accessible-grades-table.htmlCopy Code
<table border="1" style="border-collapse: collapse;">
  <caption>Student Exam Scores</caption>
  <thead>
    <tr>
      <th scope="col"></th>
      <th scope="col">Math</th>
      <th scope="col">Science</th>
      <th scope="col">English</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th scope="row">Pooja</th>
      <td>85</td>
      <td>90</td>
      <td>80</td>
    </tr>
    <tr>
      <th scope="row">Ovi</th>
      <td>92</td>
      <td>88</td>
      <td>95</td>
    </tr>
  </tbody>
</table>

Rendered Result

Student Exam Scores
MathScienceEnglish
Pooja859080
Ovi928895

Reading through this example: the <caption> announces what the table is about before a screen reader even reaches the first row, <thead> and <tbody> separate structure from data, and every single header, in both directions, carries an explicit scope value. This is meaningfully more accessible than the plain Column and Row Headers example earlier on this page, while using nothing beyond tags and attributes already introduced in this tutorial, which is exactly the point: accessible markup is rarely about learning entirely new tags, it is usually about applying the ones you already know a little more completely.

Table Headers and SEO

Search engines read the same HTML markup a screen reader does, so a well-structured table with genuine <th> headers, a descriptive <caption>, and proper <thead>/<tbody> grouping is easier for a search engine to understand and, in some cases, feature directly in search results, such as within a rich snippet or featured table preview.

Styling and Positioning the Caption

By default, a <caption> renders directly above the table, centered, in normal (non-bold) text, but CSS gives you control over both its position and appearance.

ExampleCopy Code
<style>
    caption {
        caption-side: bottom;
        font-style: italic;
        color: #64748b;
        padding: 6px 0;
    }
</style>
caption-side Value Effect
top (default)Caption appears above the table
bottomCaption appears below the table, useful for source notes

A bottom-positioned, italicized caption is a common pattern for tables that need a small source citation or footnote, such as "Source: Company internal sales data," without it competing visually with the table's actual title, which might instead be a nearby heading rather than the caption itself.

Headers Inside Nested or Complex Tables

Every example on this page uses a single, flat table, but real data occasionally calls for more complex structures, such as a table with grouped column headers spanning multiple columns. HTML supports this through the colspan and rowspan attributes on a <th> tag.

ExampleCopy Code
<table border="1">
  <tr>
    <th rowspan="2">Student</th>
    <th colspan="2">Semester 1</th>
  </tr>
  <tr>
    <th>Math</th>
    <th>Science</th>
  </tr>
  <tr>
    <td>Pooja</td>
    <td>85</td>
    <td>90</td>
  </tr>
</table>

Here, colspan="2" makes the "Semester 1" header stretch across two columns, while rowspan="2" makes the "Student" header stretch down two rows to align with the row of data below the grouped headers. This is a more advanced technique than the three core examples earlier on this page, but it builds directly on the same <th> fundamentals already covered.

Browser Support and Historical Context

The <th> tag has been part of HTML since its earliest table specification, and every browser in use today, desktop or mobile, supports it identically, along with <caption>, <thead>, <tbody>, and the scope attribute covered throughout this tutorial. Unlike some of the deprecated attributes covered elsewhere in this HTML tutorial series, nothing on this page is legacy or discouraged, this is the current, recommended way to build table headers in modern HTML.

That consistency is part of why table headers are such a reliable, low-risk place to invest a little extra care, a properly captioned, scoped table you build today will render and behave identically in any browser your visitors use for years to come, with no compatibility concerns to track.

Frequently Asked Questions About HTML Table Headers

What is the th tag used for in HTML?

The th tag defines a table header cell. It is typically placed inside a thead section, and browsers display its content bold and centered by default, unlike the plain td tag used for ordinary data cells.

What is the difference between th and td?

The th tag marks a cell as a header, rendered bold and centered by default and read differently by screen readers. The td tag marks a cell as ordinary data, with no special styling or semantic meaning.

Can a th tag be used for row headers, not just column headers?

Yes. A th tag placed at the start of a row, rather than in the top header row, labels that row the same way a column header labels a column, which is exactly how the Column and Row Headers example on this page works.

What does the scope attribute do on a th tag?

The scope attribute tells assistive technology whether a header applies to its column (scope="col") or its row (scope="row"), which helps screen reader users understand which header describes which piece of data.

Does a table need a caption tag?

A caption is not required, but it is recommended whenever a short, clear title would help a visitor or screen reader user understand what the table represents before reading through its rows.

Can I style a th tag differently from a td tag?

Yes. Since th and td are separate tags, they can be targeted independently with CSS, such as giving th cells a background color or different font weight than ordinary td cells.

What is the difference between colspan and rowspan on a th tag?

colspan makes a header cell stretch horizontally across multiple columns, while rowspan makes it stretch vertically across multiple rows, both useful for grouped or hierarchical header structures.

Where can the caption tag be placed in a table?

A caption must be placed immediately after the opening table tag, before any rows. Its visual position (top or bottom) can still be changed afterward using the CSS caption-side property.

Do table headers help with SEO?

Genuine th tags, a descriptive caption, and proper thead/tbody grouping help search engines understand a table's structure and content, which can support how that data is interpreted or featured in search results.