Skip to content

Tagged PDF (Accessibility)

The Accessibility module (StructureTreeManager, RoleMap, TaggedContentManager) enables tagged PDF output for screen readers and assistive technologies. When enabled, every piece of content is wrapped in structure elements that describe its semantic role. All tagging methods return static for chaining.

Quick Reference

MethodDescription
setTaggedPdf()Enable or disable tagged PDF mode
setLanguage()Set the document's primary language (BCP 47)
openTag()Begin a tagged structure element
closeTag()End a tagged structure element
image(..., alt:)Add an image with alt text for accessibility

Enabling Tagged PDF

php
use Yeeefang\TcpdfNext\Core\Document;

$pdf = Document::create()
    ->setTaggedPdf(true)
    ->setLanguage('en-US')
    ->addPage()
    ->setFont('Helvetica', '', 12);

When setTaggedPdf(true) is called, the StructureTreeManager is lazily initialized and a MarkInfo dictionary with Marked = true is written to the PDF catalog.

Structure Elements

TCPDF-Next supports the full PDF 2.0 standard tag set:

CategoryTags
GroupingDocument, Part, Sect, Div, BlockQuote, Caption, NonStruct
HeadingsH1, H2, H3, H4, H5, H6
ParagraphsP, Span
ListsL, LI, Lbl, LBody
TablesTable, TR, TH, TD, THead, TBody, TFoot
InlineLink, Em, Strong, Code
IllustrationsFigure, Formula, Form

Basic Tagging

php
use Yeeefang\TcpdfNext\Core\Document;

$pdf = Document::create()
    ->setTaggedPdf(true)
    ->setLanguage('en-US')
    ->addPage()
    ->setFont('Helvetica', '', 12)

    ->openTag('H1')
    ->cell(0, 10, 'Annual Report 2026', newLine: true)
    ->closeTag('H1')

    ->openTag('P')
    ->multiCell(0, 6, 'This document demonstrates tagged PDF output for accessibility compliance.')
    ->closeTag('P')

    ->save('tagged-basic.pdf');

Tags must be properly nested. The StructureTreeManager validates nesting and throws an exception on mismatch.

Tagged Tables

php
$pdf->openTag('Table')
    ->openTag('TR')
    ->openTag('TH')->cell(50, 8, 'Quarter')->closeTag('TH')
    ->openTag('TH')->cell(50, 8, 'Revenue')->closeTag('TH')
    ->closeTag('TR')
    ->openTag('TR')
    ->openTag('TD')->cell(50, 8, 'Q1')->closeTag('TD')
    ->openTag('TD')->cell(50, 8, '$1,200,000')->closeTag('TD')
    ->closeTag('TR')
    ->closeTag('Table');

Tag Attributes

Pass additional attributes when opening a tag:

php
$pdf->openTag('Figure', ['Alt' => 'Company logo', 'ActualText' => 'Acme Corp Logo'])
    ->image('/path/to/logo.png', 10, 50, 40, 40)
    ->closeTag('Figure');

Common attributes:

AttributeDescription
AltAlternative text for non-text elements
ActualTextExact text replacement for the element
LangLanguage override for this element (BCP 47)
TitleHuman-readable title

The image() method also accepts an alt parameter as a shorthand — $pdf->image('chart.png', 10, 80, 120, 60, alt: 'Revenue chart') automatically wraps the image in a Figure tag.

Role Mapping

The RoleMap maps custom tag names to standard PDF structure types. This lets you use domain-specific names while maintaining PDF/UA compatibility:

php
$pdf->openTag('Invoice', ['roleMap' => 'Sect'])
    ->openTag('LineItem', ['roleMap' => 'P'])
    ->cell(0, 8, 'Widget x 10 — $500.00', newLine: true)
    ->closeTag('LineItem')
    ->closeTag('Invoice');

The role map is written to the structure tree root so validators resolve custom tags to standard equivalents. For multilingual content, override the language per-element: ->openTag('P', ['Lang' => 'de-DE']).

PDF/UA Compliance

To produce a fully PDF/UA-compliant document, ensure:

  1. Tagged PDF is enabledsetTaggedPdf(true)
  2. Document language is setsetLanguage('en-US')
  3. All content is tagged — no untagged content outside structure elements
  4. All images have alt text — via alt: parameter or Figure tag with Alt attribute
  5. Tables use TH for headers — header cells must be distinguished from data cells
  6. Fonts are embedded — TCPDF-Next embeds all fonts by default

Integration with PDF/A-4

Tagged PDF is fully compatible with PDF/A-4. Enable both for archival + accessible documents:

php
$pdf = Document::create()
    ->setTaggedPdf(true)
    ->setPdfA(true)
    ->setLanguage('en-US')
    ->setTitle('Accessible Archival Document')
    ->addPage()
    ->setFont('Helvetica', '', 12)
    ->openTag('H1')
    ->cell(0, 10, 'PDF/A-4 + PDF/UA Document', newLine: true)
    ->closeTag('H1')
    ->save('accessible-archival.pdf');

Released under the LGPL-3.0-or-later License.