Accessible Tables in PDFs — Complete Guide
In this tutorial, you will learn about Accessible Tables in PDFs. We cover key concepts, practical examples, and best practices to help you master this topic.
Accessible tables in PDFs require proper table tags — Table, TR (table row), TH (table header), and TD (table data) — arranged in a logical structure tree so that screen readers can announce cell positions and header associations.
What You'll Learn
You will learn how tables are represented in the PDF tag tree, how to create correctly tagged tables from authoring tools, how to fix complex tables with merged cells, and how to verify that screen readers can navigate your tables.
Why It Matters
Tables are the most frequently broken structure in PDF Accessibility. When tables are untagged, screen readers read all cell content as a single text blob, making it impossible to understand which value belongs to which column or row.
Real-World Use
A financial analyst receives a PDF containing a 50-row table of stock prices. Before tagging, NVDA reads "AAPL 175.43 MSFT 390.12 GOOG 185.67" as a single string. After proper table tagging, the user presses T to jump to the table, then Ctrl+Alt+Arrow keys to navigate cell by cell with column headers announced.
Table Tag Structure
flowchart TD A["
| Symbol"] B --> D[" | Price"] B --> E[" | Change"] A --> F[" |
|---|---|---|
| AAPL"] F --> H[" | 175.43"] F --> I[" | +1.2%"] A --> J[" |
| MSFT"] J --> L[" | 390.12"] J --> M[" | -0.5%"]
Creating TablesFrom Microsoft WordUse the Insert > Table tool, not tabs or manual spacing to create visual tables. Ensure the first row is formatted as a header row (check "Header Row" in Table Design > Header Row). Word table structure:
- Table → <Table>
- Header row (checked "Header Row") → <TR> with <TH> cells
- Data rows → <TR> with <TD> cells
Fixing Tables in AcrobatIf auto-tagging produces a flat table (all
// Acrobat JavaScript to convert first row from TD to TH
var table = this.getTags().findTag("Table", 0);
if (table) {
var firstRow = table.getChildren()[0]; // First TR
if (firstRow) {
var cells = firstRow.getChildren();
for (var i = 0; i < cells.length; i++) {
cells[i].structType = "TH";
cells[i].scope = "Column";
}
console.println("First row cells converted to TH");
}
}
Complex TablesFor tables with merged headers (rowspan/colspan), use the Complex header example:
| Q1 2026 | Q2 2026 |
| Revenue | Profit | Revenue | Profit |
|---------|--------|---------|--------|
TH tag attributes:
- "Q1 2026": ColSpan=2, Scope=Column
- "Revenue": Scope=Column (under Q1)
- "Profit": Scope=Column (under Q1)
- "Q2 2026": ColSpan=2, Scope=Column
- "Revenue": Scope=Column (under Q2)
- "Profit": Scope=Column (under Q2)
Common Mistakes
Practice and Challenge
Challenge: Create a PDF with a 5-column by 8-row table (with headers) and a complex table with a multi-level header (2 header rows with merged cells). Tag both tables correctly, verify with a screen reader, and document the scope attributes used. FAQMini ProjectCreate a 2-page PDF with three tables: a simple 3x4 data table with headers, a table with a merged header row (colspan on years), and a layout table used for page design. Tag the data tables correctly and mark the layout table as an artifact. Verify table navigation with NVDA. What's NextProceed to Form Fields in PDFs to learn about accessible forms, then continue to Language Tagging in PDFs. Built by the developers of DodaTech Doda Browser, DodaZIP & Durga Antivirus Pro |