👀 Live Preview
Accessible table with scope="col" and scope="row":
| Month | Revenue | Expenses |
|---|---|---|
| January | $10,000 | $7,000 |
| February | $12,000 | $8,500 |
Screen readers use scope to associate “January” with its row and “Revenue” with its column.

The scope attribute is used on <th> header cells in HTML tables to describe which cells a header labels. It helps screen readers and other assistive technologies understand row and column relationships, making tabular data easier to navigate for everyone.
Where scope applies.
Column headers.
Row headers.
Grouped row headers.
Grouped column headers.
Set scope dynamically.
scopeThe main purpose of the scope attribute is to specify the relationship between header cells (<th>) and the data cells (<td>) they describe. Without this hint, a screen reader user hearing “$10,000” may not know whether it is January’s revenue or February’s expenses.
By marking column headers with scope="col" and row headers with scope="row", you expose the table’s logical structure to assistive technology in a simple, declarative way.
scope does not change visual layout—it improves how tables are announced. Pair it with a clear <caption>, proper <thead>/<tbody> structure, and meaningful header text.
Add scope to <th> elements with one of four keyword values:
<th scope="col">Revenue</th>
<th scope="row">January</th><th> elements in <table>, <thead>, <tbody>, and <tfoot>.row, col, rowgroup, or colgroup.col for headers that label columns; row for headers that label rows.rowgroup or colgroup when a header spans a group via rowspan or colspan.scope on <td> data cells—use <th> for headers instead.headers attribute on <td> can complement or replace scope.The scope attribute accepts exactly four enumerated values:
row — The header applies to all cells in the same row (typical for the first cell in a data row).col — The header applies to all cells in the same column (typical for headers in <thead>).rowgroup — The header applies to a group of rows, often when the <th> spans multiple rows with rowspan.colgroup — The header applies to a group of columns, often when the <th> spans multiple columns with colspan.<!-- Column header in thead -->
<th scope="col">Month</th>
<!-- Row header in tbody -->
<th scope="row">January</th>
<!-- Header spanning a row group -->
<th scope="rowgroup" rowspan="2">Q1</th>| Header type | scope value | Typical placement |
|---|---|---|
| Column label | col | <thead> top row |
| Row label | row | First <th> in each <tr> |
| Multi-row group label | rowgroup | <th rowspan="n"> |
| Multi-column group label | colgroup | <th colspan="n"> |
| Applicable element | <th> | Not on <td> |
| JavaScript | th.scope = "row" | Dynamic tables |
| Element | Supported? | Notes |
|---|---|---|
<th> | Yes | Primary and intended use |
<td> | No | Use <th> for headers; use headers on td if needed |
<table> | No | Put scope on th cells inside the table |
<input> | No | Not related to form controls |
scope vs headers vs id| Approach | Used on | Best for |
|---|---|---|
scope | <th> | Most tables with clear row/column headers |
headers | <td> | Complex tables with irregular header associations |
id on th + headers on td | Both | Explicit many-to-many header links |
Start with scope for straightforward data tables. Reach for headers when a single data cell is labeled by multiple non-adjacent headers.
Monthly report with column and row headers, rowgroup for quarterly sections, and dynamic th.scope in JavaScript.
Accessible table with scope="col" and scope="row":
| Month | Revenue | Expenses |
|---|---|---|
| January | $10,000 | $7,000 |
| February | $12,000 | $8,500 |
Screen readers use scope to associate “January” with its row and “Revenue” with its column.
A simple financial table with column headers in <thead> and row headers in <tbody>:
<table>
<caption>Monthly Report</caption>
<thead>
<tr>
<th scope="col">Month</th>
<th scope="col">Revenue</th>
<th scope="col">Expenses</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">January</th>
<td>$10,000</td>
<td>$7,000</td>
</tr>
<tr>
<th scope="row">February</th>
<td>$12,000</td>
<td>$8,500</td>
</tr>
</tbody>
</table>scope="col" on Month, Revenue, and Expenses labels their columns. scope="row" on January and February labels their rows. A screen reader can announce “January, Revenue, $10,000” instead of a bare number.
rowgroup for Grouped RowsWhen a header spans multiple rows, use scope="rowgroup":
<table>
<thead>
<tr>
<th scope="col">Quarter</th>
<th scope="col">Month</th>
<th scope="col">Sales</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="rowgroup" rowspan="2">Q1</th>
<th scope="row">January</th>
<td>100</td>
</tr>
<tr>
<th scope="row">February</th>
<td>120</td>
</tr>
</tbody>
</table>rowgroup tells assistive tech that the header applies to a set of rows, not just one. Use colgroup similarly when a column header spans multiple columns with colspan.
Set scope when building or updating tables at runtime:
<table id="dataTable">
<tr>
<th id="dynamicHeader">Name</th>
<td>John</td>
</tr>
</table>
<script>
document.getElementById("dynamicHeader").scope = "row";
</script>HTMLTableCellElement.scope reflects the content attribute. When you add rows via JavaScript, set scope on each new <th> as you create it—do not rely on visual position alone.
scope="col" and row headers scope="row" consistently.<caption> gives the table a title for all users, not just screen reader users.<td> with bold styling as a fake header; use <th> with scope.headers attribute.col, row, rowgroup, or colgroup.
Links headers to data cells.
Announces row and column labels.
Users understand every cell in context.
The scope attribute is supported in all modern browsers on <th> elements and is reflected by the scope IDL property.
All major browsers expose scope on header cells for the accessibility tree.
Bottom line: Use scope confidently on <th> cells in all modern projects.
scope="col" to every column header in <thead>scope="row" to row header <th> cells in <tbody>rowgroup and colgroup when headers span multiple rows or columns<caption> on data tablesscope on <td> data cellscol and row values on the wrong header typescope on dynamically inserted <th> elementsThe scope attribute is a crucial tool for improving the accessibility and structure of HTML tables. By marking header relationships explicitly, you help assistive technologies interpret tabular data correctly.
Use scope="col" and scope="row" on every appropriate <th>, reach for rowgroup and colgroup when headers span groups, and combine scope with captions and semantic table markup for the best results.
scopeBookmark these before your next data table.
Header cells
ScopeColumn labels
ValueRow labels
Valuerowgroup / colgroup
AdvancedScreen reader context
Why<th> header labels a row, column, row group, or column group in a table.<th> header cells only. Do not use scope on <td> data cells.col for headers across the top (column labels). Use row for headers in the first column of each row (row labels).thElement.scope = "row" or use setAttribute("scope", "col") when building tables dynamically.<th> elements.Practice scope="col" and scope="row" on a monthly report table in the Try It editor.
5 people found this page helpful