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.
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
<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
| Product | Price | Quantity |
|---|---|---|
| Laptop | $1000 | 2 |
| Phone | $500 | 5 |
🧹 2. Column and Row Headers
<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
| Math | Science | English | |
|---|---|---|---|
| Pooja | 85 | 90 | 80 |
| Ovi | 92 | 88 | 95 |
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)
<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
| Month | Savings |
|---|---|
| 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.
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 header | Marks a cell as ordinary data |
| Bold and centered by default | Normal weight and left-aligned by default |
| Announced distinctly by screen readers | Read as plain content |
| Can appear in a header row or as a row label | Never 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.
<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.
- Column headers (the Syntax of Table Headers example) suit data where every row represents one record, and each column represents a different attribute of that record, such as Product, Price, and Quantity.
- Row headers (the left-hand "Pooja" and "Ovi" labels) suit data where each row itself needs its own label, common in grade sheets, comparison matrices, or any table where a row is the "subject" being described.
- Combining both, as the Column and Row Headers example does, works well for cross-referenced data, such as a grid comparing multiple students across multiple subjects at once.
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.
<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
- Using <td> styled to look bold instead of a real <th> tag, losing the semantic and accessibility benefits header cells provide automatically.
- Forgetting an empty <th></th> in the top-left corner of a table with both row and column headers, which throws off the alignment of every column that follows it.
- Skipping the scope attribute on tables with headers running in both directions, leaving assistive technology to guess which header belongs to which data.
- Placing a <caption> anywhere other than immediately after the opening <table> tag, which is the only position HTML allows it in.
- Mixing up <thead> with <th>, two similarly named but different tags, one grouping header rows, the other marking an individual header cell.
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:
- Recreate the Syntax of Table Headers example, then add a fourth column with its own header.
- Build a table with row headers only, no column headers, labeling three rows of data.
- Add scope="col" and scope="row" to the Column and Row Headers example.
- Add a <caption> to a table you build from scratch, describing what it shows.
- 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:
<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
| Math | Science | English | |
|---|---|---|---|
| Pooja | 85 | 90 | 80 |
| Ovi | 92 | 88 | 95 |
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.
- A clear caption gives both visitors and search engines an at-a-glance summary of what the table contains.
- Genuine header cells help a search engine associate each column's label with the data beneath it, rather than treating the whole table as an undifferentiated block of text.
- None of this replaces good content, proper table structure simply makes genuinely useful tabular data easier for both people and machines to interpret correctly.
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.
<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 |
| bottom | Caption 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.
<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.