Guide
How to tag a table in a PDF for accessibility
Table structure, header scope, and the point where Scope stops working and Headers references become necessary.
About 18 minutes · involved
The grammar
ISO 32000-1 Table 337 defines what may contain what, and it is short:
Table
├── Caption (optional, first)
├── THead → TR → TH
├── TBody → TR → TH | TD
└── TFoot → TR → TH | TD
TR may only appear in Table, THead, TBody or TFoot. TH and TD may only appear in TR. Anything else is condition 09-004, and Acrobat’s Table Editor will refuse to open a table whose grammar is broken — which is a useful diagnostic in itself.
Headers, in two ways
/Scope on each TH: Row, Column or Both. Sufficient for a regular grid.
/Headers on each data cell: an array of /ID strings naming the headers that govern it. Necessary once the table is irregular.
You must use one or the other. A TH with no /Scope in a table with no /Headers is condition 15-003.
Doing it free, in Acrobat Pro
- Tags panel → find the
<Table>→ right-click → Table Editor. If it is greyed out, the grammar is broken. Fix that first. - The page shows a coloured grid. Red is
TH, grey isTD. - Any header showing grey: right-click → Table Cell Properties → Type: Header Cell.
- Set Scope in the same dialog.
- Shift-click a run of cells in one row to set them together — this is the one place Acrobat gives you multi-select and it saves real time.
- For complex tables, use Associated Header Cell IDs in the same dialog, one cell at a time.
Step 6 is where a 5×20 table becomes 100 dialogs. There is no free way around it.
Upstream is dramatically faster
Word: select the header row → Table Tools → Layout → Repeat Header Rows, 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.
InDesign: Table → Convert Rows → To Header.
Both take seconds and survive the next revision. If you have the source, this is not a close call.
Where Taggart fits
Setting /Scope on cells that are already TH is mechanical, and Taggart infers the right value from position: a cell in an all-TH row heads its column, a leading cell in a body row heads its row, a corner cell in a stacked header gets Both. That ships in “Fix All Safe”.
Promoting a TD to a TH is a claim about what the document means, so it needs your approval.
And Taggart detects the case where /Scope is not enough — spanning cells or stacked header rows — and reports it as 15-005 rather than writing a /Scope that would look conformant and still mislead a reader.
Frequently asked questions
Is this a data table or a layout table?
Ask whether any cell's meaning depends on its row and column. If yes, it is data and needs table structure. If the grid exists only to position things on the page, it is layout and should not be tagged as a table at all — that is condition 15-004.
When do I need Headers and IDs instead of Scope?
As soon as there are merged cells or more than one header row. Scope can say 'this heads its row' or 'its column' and nothing more, which cannot express a header governing three of five columns.
What about nested tables?
A table inside a cell is legal but hostile to read. If you can restructure it into two tables, do. If you cannot, every cell in both tables needs explicit Headers references, because Scope cannot cross the nesting boundary.
Related failure conditions
- 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-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.
- 09-004 A table-related structure element does not conform to ISO 32000-1, Table 337 The table grammar is broken: a TD outside a TR, a TR outside Table/THead/TBody/TFoot, a Table with no rows.
Check your own file. Taggart's validator is free and unlimited — no page cap, no watermark, no account.
Last updated .