HTML headers Attribute

Beginner
⏱️ 6 min read
📚 Updated: Jun 2026
🎯 3 Examples
Tables & Accessibility

What You’ll Learn

The headers attribute links table data cells to their header cells using space-separated id values. Screen readers use these associations to announce which row and column headers apply to each cell—especially important in complex tables with merged cells or multi-level headers.

01

Header Links

Reference th id values.

02

td and th

Where headers applies.

03

Space-Separated

Multiple ids allowed.

04

Complex Tables

rowspan and colspan.

05

scope vs headers

When to use each.

06

JavaScript

cell.headers property.

Purpose of headers Attribute

The headers attribute is used on <td> and <th> elements to explicitly associate a cell with one or more header cells. Each referenced header must have a unique id attribute. This helps assistive technologies understand the relationship between data and the labels that describe it.

In simple tables with a single row of column headers and a single column of row headers, the scope attribute on <th> is often sufficient. The headers attribute becomes essential when scope alone cannot express the relationships—for example, when headers span multiple rows or columns with rowspan and colspan.

💡
Accessibility first

The headers attribute has no visual effect. It exists purely to improve how screen readers announce table content. Always pair it with semantic structure: <thead>, <tbody>, and a descriptive <caption>.

📝 Syntax

Add headers to a <td> or <th> with a space-separated list of header cell id values:

headers.html
<table>
  <thead>
    <tr>
      <th id="name" scope="col">Name</th>
      <th id="score" scope="col">Score</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td headers="name">Alice</td>
      <td headers="score">92</td>
    </tr>
  </tbody>
</table>

Syntax Rules

  • Valid on <td> and <th> elements inside a table.
  • Value is a space-separated list of id values from header cells (<th>).
  • Each referenced id must be unique within the document.
  • A cell may reference multiple headers when it belongs to more than one row or column label.
  • For simple tables, scope on <th> is often enough; use headers when relationships are ambiguous.

💎 Values

The headers attribute accepts one or more header cell id values, separated by spaces:

  • headers="name" — Associates the cell with a single column or row header.
  • headers="north q1 q1-sales" — Associates a cell with multiple headers: a row header, a group header, and a sub-header.
  • headers="region q2-units" — Common in sales or financial tables with nested column groups.
headers-values.html
<!-- Single header reference -->
<td headers="product">Widget A</td>

<!-- Multiple header references -->
<td headers="west q3 q3-revenue">$48,200</td>

⚡ Quick Reference

ConceptDetailsNotes
Applies to<td>, <th>Table cells only
Value formatSpace-separated id liste.g. "row1 col2"
Header requirementReferenced cells need idEach id must be unique
Simple tablesscope on <th>Often sufficient alone
Complex tablesheaders on data cellsNeeded with rowspan/colspan
JS propertycell.headersString of space-separated ids

Applicable Elements

ElementSupported?Notes
<td>YesPrimary use — link data cells to headers
<th>YesSub-headers in complex layouts may reference parent headers
<table>NoSet headers on individual cells
<div>, <span>NoTable-cell attribute only

scope vs headers

ApproachExampleWhen to Use
scope="col"<th scope="col">Name</th>Simple tables with one header row
scope="row"<th scope="row">Total</th>Simple row header labels
headers="id1 id2"<td headers="region q1-sales">Complex tables with merged or nested headers
Combinedscope + headersBest practice for large accessible tables

Examples Gallery

Basic header association, a multi-level sales table with rowspan and colspan, and dynamic headers with JavaScript.

👀 Live Preview

Simple table with headers linking data cells to column header ids:

NameScore
Alice92
Bob87

Example — Basic Table with Header ids

Here’s a straightforward table using <thead>, <tbody>, and headers to link each data cell to its column header:

basic-headers.html
<table>
  <caption>Student Scores</caption>
  <thead>
    <tr>
      <th id="name" scope="col">Name</th>
      <th id="score" scope="col">Score</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td headers="name">Alice</td>
      <td headers="score">92</td>
    </tr>
    <tr>
      <td headers="name">Bob</td>
      <td headers="score">87</td>
    </tr>
  </tbody>
</table>
Try It Yourself

How It Works

Each <th> has a unique id. Data cells use headers to point at the matching header id. Even though scope="col" already helps in this simple layout, explicit headers references reinforce the association for assistive technology.

Example — Complex Multi-Header Sales Table

When headers span rows and columns, scope alone may not be enough. Use headers to link each data cell to all relevant labels:

complex-headers.html
<table>
  <caption>Quarterly Sales by Region</caption>
  <thead>
    <tr>
      <th id="region" rowspan="2">Region</th>
      <th id="q1" colspan="2">Q1</th>
      <th id="q2" colspan="2">Q2</th>
    </tr>
    <tr>
      <th id="q1-sales" headers="q1">Sales</th>
      <th id="q1-units" headers="q1">Units</th>
      <th id="q2-sales" headers="q2">Sales</th>
      <th id="q2-units" headers="q2">Units</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th id="north" scope="row">North</th>
      <td headers="north q1 q1-sales">$12,400</td>
      <td headers="north q1 q1-units">310</td>
      <td headers="north q2 q2-sales">$14,800</td>
      <td headers="north q2 q2-units">370</td>
    </tr>
    <tr>
      <th id="south" scope="row">South</th>
      <td headers="south q1 q1-sales">$9,600</td>
      <td headers="south q1 q1-units">240</td>
      <td headers="south q2 q2-sales">$11,200</td>
      <td headers="south q2 q2-units">280</td>
    </tr>
  </tbody>
</table>
Try It Yourself

How It Works

The Q1 and Q2 group headers use colspan, and sub-headers reference them with headers="q1". Data cells list all three relevant ids—row, group, and sub-header—so screen readers can announce the full context, such as “North, Q1, Sales: $12,400.”

Dynamic Values with JavaScript

You can set or update the headers attribute at runtime when table structure changes dynamically:

dynamic-headers.html
<table>
  <tr>
    <th id="headerId">Revenue</th>
  </tr>
  <tr>
    <td id="dataCell">$5,000</td>
  </tr>
</table>

<script>
  var cell = document.getElementById("dataCell");
  cell.headers = "headerId";
  // or: cell.setAttribute("headers", "id1 id2");
</script>
Try It Yourself

How It Works

The script assigns the header id to the data cell at runtime. This is useful when rows or columns are added dynamically and you need to maintain correct header associations without rewriting the entire table markup.

♿ Accessibility

  • Give every header a unique id — Referenced ids must exist and be unique within the page.
  • Use headers for complex layouts — When rowspan, colspan, or nested headers break simple scope relationships.
  • Add a <caption> — Summarize the table purpose before users navigate individual cells.
  • Prefer semantic structure — Wrap headers in <thead> and data rows in <tbody>.
  • Test with screen readers — Verify that NVDA, VoiceOver, or JAWS announce the correct header labels for each cell.
  • Do not rely on visual position alone — Merged cells can confuse assistive tech without explicit headers references.

🧠 How headers Works

1

Author assigns ids to headers

Each th gets a unique id attribute.

Markup
2

Data cells reference header ids

headers lists space-separated id values.

Association
3

Browser builds accessibility tree

Cell-to-header relationships exposed to AT.

Platform
=

Clear table navigation

Screen readers announce full header context.

Browser Support

The headers attribute is fully supported in all modern browsers on <td> and <th> elements. Correct markup matters more than browser quirks—assistive technology depends on valid id references.

HTML4 · Fully supported

Universal table header association

All major browsers expose headers in the accessibility tree for table cells.

99% Browser support
Google Chrome Fully supported
Full support
Mozilla Firefox Fully supported
Full support
Apple Safari Fully supported
Full support
Microsoft Edge Fully supported
Full support
headers attribute 99% supported

Bottom line: Use headers confidently for complex tables; validate with a screen reader to confirm associations.

💡 Best Practices

✅ Do

  • Assign unique id values to every header cell
  • Use headers when rowspan or colspan breaks simple scope
  • Include a descriptive <caption> on data tables
  • Combine scope and headers in large tables
  • Test table navigation with screen reader software

❌ Don’t

  • Reference ids that do not exist on the page
  • Duplicate id values across header cells
  • Skip headers in complex multi-level layouts
  • Assume visual alignment equals accessible structure
  • Use tables for page layout instead of data

Conclusion

The headers attribute is a powerful accessibility tool for HTML tables. By linking data cells to their header cells through space-separated id references, you help screen reader users understand complex tabular data with confidence.

For simple tables, scope on <th> may be enough. When your layout uses merged cells or nested headers, headers fills the gap that scope alone cannot cover. Always validate your work with assistive technology.

Key Takeaways

Knowledge Unlocked

Five truths every developer should know about headers

Bookmark these before building accessible tables.

5
Core concepts
📊 02

td and th

Cell attribute.

Scope
03

For complex tables

rowspan/colspan.

A11y
⚙️ 04

cell.headers

Set in JavaScript.

Script
📝 05

scope first

headers when needed.

Pattern

❓ Frequently Asked Questions

It links a table cell to one or more header cells by referencing their id values. Screen readers use these associations to announce which row and column headers apply to each cell.
<td> and <th> elements inside a table. Referenced header cells must have matching id attributes.
scope on <th> declares row or column direction and works well for simple tables. headers explicitly lists header ids and is needed when relationships are ambiguous due to merged cells.
Use headers when a data cell belongs to multiple headers—for example, a sales figure tied to both a region row and a quarter column in a table with rowspan or colspan.
Use cell.headers = "headerId" or cell.setAttribute("headers", "id1 id2") with a space-separated list of header ids.
Yes. All modern browsers support the headers attribute. Focus on correct id references and table structure for reliable assistive technology behavior.

Build accessible tables

Practice the headers attribute with basic and complex table examples in the Try It editor.

Try basic headers example →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

4 people found this page helpful