Data tables without semantic markup are read by screen readers as an undifferentiated stream of cell values—users hear numbers and words but cannot determine which column header or row label a cell belongs to. <th> elements with scope attributes are the mechanism that associates data cells with their headers, enabling screen readers to announce "Region: North America, Sales: $2.5M" instead of just "North America $2.5M". WCAG 2.2 SC 1.3.1 (Level A) requires information conveyed through presentation to be programmatically determinable. Section 508 2018 Refresh 502.3.6 specifically requires that tables preserve semantic meaning for AT. Complex tables (multi-level headers, row spans) that lack semantic markup are entirely unusable for blind users.
Low because table markup failures affect specific data components rather than navigation or form submission, but they completely destroy the meaning of tabular data for screen reader users of those tables.
Refactor every <table> to use <thead>, <tbody>, column <th scope="col">, and row <th scope="row"> elements. Add a <caption> that describes what the table shows:
<table>
<caption>Q3 2024 Revenue by Region</caption>
<thead>
<tr>
<th scope="col">Region</th>
<th scope="col">Revenue</th>
<th scope="col">YoY Growth</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">North America</th>
<td>$2.5M</td>
<td>+12%</td>
</tr>
<tr>
<th scope="row">Europe</th>
<td>$1.8M</td>
<td>+7%</td>
</tr>
</tbody>
</table>
For complex tables with merged cells, use headers attribute instead of scope to explicitly list the ids of all associated header cells.
ID: gov-section-508.multimedia-documents.table-markup
Severity: low
What to look for: Count all relevant instances and enumerate each. Find all <table> elements on the site. Check whether they use semantic structure: <thead> for header rows, <tbody> for body rows, <th> elements with scope="col" (column headers) and scope="row" (row headers). Check for a <caption> element describing the table's purpose.
Pass criteria: Tables use <thead>, <tbody>, and <tfoot> (where applicable). All header cells use <th> with appropriate scope attributes. A <caption> or descriptive text precedes the table.
Fail criteria: Tables use only <tr> and <td> elements with no header markup, or headers lack scope attributes.
Skip (N/A) when: No tables exist on the site.
Detail on fail: Example: "Data table on /reports uses only <tr> and <td> elements. No <thead>, <th>, or <caption>. Screen reader users cannot determine which columns or rows are headers."
Remediation: Structure tables semantically:
<table>
<caption>Q3 Sales by Region</caption>
<thead>
<tr>
<th scope="col">Region</th>
<th scope="col">Sales</th>
<th scope="col">Growth</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">North America</th>
<td>$2.5M</td>
<td>+12%</td>
</tr>
</tbody>
</table>
Cross-reference: For related patterns and deeper analysis, see the corresponding checks in other AuditBuffet audits covering this domain.