Matterhorn 15-002 · PDF/UA-1 UA1:7.5-1
Table with no header cells at all
The top row labels the columns but is tagged as ordinary data cells.
The condition, as the protocol states it. “A column has a header cell, but that header cell is not tagged as a header.”
Matterhorn Protocol 1.1, checkpoint 15, index 15-002, section UA1:7.5-1. The protocol marks this as requiring human judgement.
What a screen reader actually does
Moving across a row, the reader announces bare values with no column names — "4,120. 3,980. 6,014."
What is in the file
A header cell differs from a data cell in exactly one way — its structure type:
23 0 obj << /Type /StructElem /S /TR /K [24 0 R 25 0 R 26 0 R] >>
24 0 obj << /Type /StructElem /S /TH /A << /O /Table /Scope /Column >> /K [11] >>
25 0 obj << /Type /StructElem /S /TH /A << /O /Table /Scope /Column >> /K [12] >>
26 0 obj << /Type /StructElem /S /TH /A << /O /Table /Scope /Column >> /K [13] >>
Condition 15-002 fires when a table of two or more rows contains no TH anywhere. Bold text, a shaded background and a rule underneath make a header row look like one; none of them are visible to assistive technology.
What the user hears
With headers, moving right along a row in NVDA (Ctrl + Alt + →):
Q1, 4,120. Q2, 3,980. Q3, 6,014.
Without them:
4,120. 3,980. 6,014.
On a three-column table a determined user can hold the columns in their head. On a twelve-column financial table they cannot, and the table is effectively a list of numbers in an unknown order.
The failure compounds with row headers. A table with neither means every cell is announced as a bare value with no indication of which row or column it belongs to.
How to check it free
Any screen reader, in twenty seconds. Press T in NVDA to jump to the table, then Ctrl + Alt + → to move across a row. If you hear only values, there are no headers.
Acrobat’s Table Editor. Right-click the <Table> in the Tags panel → Table Editor. Header cells are shaded red, data cells grey. An all-grey table has no headers.
How to fix it free, in Acrobat Pro
- Tags panel → find the
<Table>→ right-click → Table Editor. If it is greyed out, the table grammar is broken; fix 09-004 first. - Select the header row: click the first cell, then shift-click the last.
- Right-click → Table Cell Properties.
- Set Type to Header Cell.
- Set Scope to Column.
- Repeat for the first column if it labels rows, with Scope Row.
- Close the editor and re-check.
The shift-click multi-select in step 2 is the one place Acrobat lets you do a whole row at once, and it turns a twelve-dialog job into one.
Upstream, and much faster: in Word, select the header row and tick Repeat as header row at the top of each page in Table Properties. Word exports it as TH with /Scope /Column already set. In InDesign: Table → Convert Rows → To Header. Both take seconds and survive the next revision of the document.
Where Taggart differs
Taggart reports the table with its dimensions and quotes the first row, so you can see immediately whether it found a real header row:
This 14-row table contains no
<TH>cells at all. If its first row labels the columns those cells should be<TH>with /Scope /Column. firstRowText: [“Region”, “Q1”, “Q2”, “Q3”, “Q4”]
That quoted row is the useful part. Reading ["Region", "Q1", "Q2"] you know instantly it is a header row; reading ["North", "4,120", "3,980"] you know the table starts with data and the header is somewhere else — or missing from the document entirely.
Promoting a TD to a TH is a claim about what the document means, so Taggart requires your approval for it. Once the cells are headers, setting /Scope correctly is mechanical and ships in “Fix All Safe” — that is 15-003.
How Taggart handles it
The protocol marks this condition as needing human judgement, so no validator can decide it outright. Taggart applies a heuristic to find the likely cases and reports them as warnings for you to confirm — it never passes them silently, and it never fails them silently either.
The fix is Set table headers, Scope and Headers references. It changes what the document means, so Taggart proposes it and waits for your approval rather than applying it unattended.
Whatever Taggart changes, the page still looks identical. Fixes edit the PDF object model, not the content streams, and every remediation is re-rendered and compared against the original at structural similarity ≥ 0.999 before you get the file back. A tool that quietly reflows your document is worse than no tool.
Frequently asked questions
Does every table need header cells?
Every data table does. A table where cell meaning depends on its row and column needs headers to express that. A grid used only to position content on the page is not a data table and should not be tagged as one at all — that is condition 15-004.
Which row is the header row?
The one whose cells name what the columns contain, which is usually but not always the first. Some tables have a title row above the header row; some have two stacked header rows. Read the table and decide, then check that the reader announces what you expect.
What about the first column?
If the leftmost cell of each row labels that row — a region name, a line item, a date — it is a row header and should be a TH with /Scope /Row. That is condition 15-001, and it is the one people forget.
Why is this a warning and not a blocker?
Because the protocol marks it as requiring human judgement: only a person can say whether a given cell labels the others. Taggart applies a heuristic to find the likely cases and reports them for confirmation — it never fails a table outright on a guess.
Where this sits in the standards
| Standard | Reference |
|---|---|
| Matterhorn Protocol 1.1 | Checkpoint 15 (Tables), index 15-002 |
| PDF/UA-1 (ISO 14289-1) | Clause 7.5-1 |
| WCAG 2.1 | 1.3.1 Info and Relationships — Level A |
| EN 301 549 / Section 508 / ADA Title II | All three point at WCAG 2.1 Level AA for non-web documents, so a Level A or AA criterion here is in scope for each of them. |
Related conditions
- 15-001 A row has a header cell, but that header cell is not tagged as a header The leftmost (or, in RTL, rightmost) cell of each row labels the row but is tagged TD instead of TH.
- 15-003 A TH cell does not contain a Scope attribute Header cells must declare whether they head a row, a column, or both, unless the table instead uses explicit /Headers ID references on every data cell.
- 15-005 A given cell's header cannot be unambiguously determined In a complex table — merged cells, stacked header rows, split spans — Scope alone cannot express the associations, so explicit /Headers references are required.
- 15-004 Content is tagged as a table for information not organized in rows and columns A table used purely to position content on the page — a two-column layout, a form arrangement — has been tagged as a real table.
Other conditions in checkpoint 15
Checkpoint 15 covers tables. These are its other failure conditions; the ones without a link are in the rule set but do not have a written page yet.
- 15-001 A row has a header cell, but that header cell is not tagged as a header The leftmost (or, in RTL, rightmost) cell of each row labels the row but is tagged TD instead of TH.
- 15-003 A TH cell does not contain a Scope attribute Header cells must declare whether they head a row, a column, or both, unless the table instead uses explicit /Headers ID references on every data cell.
- 15-004 Content is tagged as a table for information not organized in rows and columns A table used purely to position content on the page — a two-column layout, a form arrangement — has been tagged as a real table.
- 15-005 A given cell's header cannot be unambiguously determined In a complex table — merged cells, stacked header rows, split spans — Scope alone cannot express the associations, so explicit /Headers references are required.
Check your own file. Taggart’s validator is free and unlimited — every machine-checkable Matterhorn condition, no watermark, no expiry, and no account needed up to 60 pages.
Verified against a real document on . Last updated .