Missing Table Headers
What is this issue?
Missing table headers occur when data tables use <td> elements for all cells without using <th> elements to identify row and column headers. WCAG Success Criterion 1.3.1 (Level A) requires that information and relationships conveyed through visual presentation are also programmatically determinable. For data tables, this means header cells must be marked up with <th> and associated with their data cells so assistive technologies can announce the context of each cell.
When a screen reader user navigates a data table, the software announces the column and row headers as the user moves between cells. Without <th> elements, the screen reader can only announce the cell content with no context. A user hearing "$4,500" has no idea whether that is a price, a quantity, a revenue figure, or a date unless the header relationship is established.
This issue is especially common in tables generated by CMS plugins, JavaScript frameworks, and data visualization libraries. Many table components render all cells as <td> and rely solely on visual styling (bold text, background color) to distinguish headers from data. Some developers avoid tables entirely and use CSS grids to create table-like layouts, which removes all semantic table structure.
Impact on users
For screen reader users, navigating a data table without headers is like looking at a spreadsheet where all the column and row labels have been deleted. Each cell value is meaningless without context. A table of employee information where the user hears "John, Smith, Engineering, 2019" is only useful if the headers "First Name, Last Name, Department, Start Year" are announced alongside each value.
Complex tables with merged cells or multi-level headers are even more problematic without proper markup. The scope attribute on <th> elements (scope="col", scope="row") and the headers attribute on <td> elements establish these relationships. Without them, complex table data is completely inaccessible.
Data tables are used extensively in business applications, financial reports, product comparisons, and scheduling tools. Missing headers in these critical contexts can prevent users from performing their job duties, making purchasing decisions, or accessing essential information.
Code example
<!-- Table without header markup -->
<table>
<tr>
<td><b>Product</b></td>
<td><b>Price</b></td>
<td><b>Stock</b></td>
</tr>
<tr>
<td>Widget A</td>
<td>$29.99</td>
<td>142</td>
</tr>
<tr>
<td>Widget B</td>
<td>$49.99</td>
<td>38</td>
</tr>
</table><!-- Table with proper headers and caption -->
<table>
<caption>Current product inventory</caption>
<thead>
<tr>
<th scope="col">Product</th>
<th scope="col">Price</th>
<th scope="col">Stock</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">Widget A</th>
<td>$29.99</td>
<td>142</td>
</tr>
<tr>
<th scope="row">Widget B</th>
<td>$49.99</td>
<td>38</td>
</tr>
</tbody>
</table>How Scrutia detects this issue
Scrutia identifies all data tables on your pages and checks for the presence of <th> elements with appropriate scope attributes. It flags tables that use <td> for header cells, tables with complex structures lacking headers attributes, and layout tables incorrectly using data table markup. The report includes the table location and a corrected markup example.
Check your site for this issue
Scrutia audits your site against WCAG criteria in minutes.
Frequently Asked Questions
When should I use scope vs. headers attributes?
Should layout tables have headers?
What is the purpose of the <caption> element?
Does your site have this issue?
Scrutia scans your pages against WCAG success criteria and delivers actionable fixes. Results in 5 minutes.
Run a free audit