Links & annotations in PDF

Annotations are the parts of a PDF that sit on top of the page rather than in it: links, comments, form widgets, stamps, embedded media, file attachments, printer marks. They are stored separately from the page content, and that separation is exactly where accessibility breaks. A link can be perfectly clickable with a mouse and completely invisible to a screen reader, because the clickable rectangle and the words under it are two unrelated objects unless the tag tree joins them.

This lesson covers the four ways that goes wrong: a link annotation that is not inside a Link tag or has nothing to announce, annotations missing from the tag tree or from the page’s tab order, review comments tagged in the wrong place, and the long tail of media, attachments and printer marks that each need their own treatment.

What you’ll learn

Why a Link tag must contain both the visible text and the link annotation itself; how /Contents and /Alt give a link or annotation something to announce; why every page carrying annotations needs /Tabs /S so keyboard order follows the structure; where markup annotations and their popups belong in the tree; and how to handle embedded media, file attachments and printer marks.

Standards this lesson maps to
Standard Criterion Level What it requires
PDF/UA-2 ISO 14289-2 § 8.9 Annotations Annotations must be represented in the structure tree, carry a text description, and appear in a defined tab order.
WCAG 2.2 1.1.1 Non-text Content A Media, stamps and other non-text annotations need a text alternative.
WCAG 2.2 2.4.4 Link Purpose (In Context) A The purpose of each link must be determinable from its text or its context.
WCAG 2.2 2.4.3 Focus Order A Focusable elements receive focus in an order that preserves meaning and operability.
EN 301 549 Clause 10 (non-web documents) Applies the WCAG criteria above to documents rather than web pages.

The four problems we’ll fix

Each card isolates one annotation defect. The Bad and Good examples show the document’s underlying tag tree and annotation dictionaries — written as escaped, non-running text — and the Code panel shows how to produce the good version from the source or in Acrobat.

Annotations missing from the structure tree or the tab order

PDF/UA-2 WCAG 2.2 · 2.4.3 A EN 301 549 ADA Title II

Every annotation that is not an artifact has to appear in the structure tree, and every page that carries annotations has to declare that its tab order follows that structure. Both are easy to miss because neither has any visual consequence. An untagged annotation is simply absent for anyone reading through the tag tree — the comment, stamp or widget is on the page but not in the document. And when a page has no /Tabs entry, keyboard order falls back to the order annotations happen to appear in the file, which is usually creation order: Tab jumps from a field near the top to one added later at the bottom, then back up again.

Checks this covers: ANNOT_TAGGED, ANNOT_TAB_ORDER — open any one for the full step-by-step fix.

Bad

A stamp annotation exists on the page but appears nowhere in the tree, and the page never declares a tab order.

annots-untagged.txt
<< /Type /Page
   /Annots [ 12 0 R  13 0 R  14 0 R ]
   ...                          <!-- no /Tabs entry at all -->
>>

12 0 obj << /Subtype /Stamp /Contents (Approved) >>   <!-- not in tree -->
13 0 obj << /Subtype /Widget /T (Full name) >>
14 0 obj << /Subtype /Link >>

Structure tree contains OBJR references for 13 and 14 only.

Result: the stamp is invisible to assistive technology,
        and Tab order = 12 → 13 → 14 (file order, not reading order).

Good

Every non-artifact annotation is referenced from the tree, and the page declares /Tabs /S so tab order follows the structure.

annots-tagged.txt
<< /Type /Page
   /Annots [ 12 0 R  13 0 R  14 0 R ]
   /Tabs /S                     <!-- S = follow Structure order -->
>>

<Document>
  <P>Invoice 2026-114</P>
  <Annot Alt="Approved stamp">
    <Stamp-OBJR/>               <!-- 12: now present in the tree -->
  </Annot>
  <Form>
    <Widget-OBJR/>              <!-- 13 -->
  </Form>
  <Link>
    <Span>Payment terms</Span>
    <Link-OBJR/>                <!-- 14 -->
  </Link>
</Document>

Code

/Tabs /S is a per-page setting, so it has to be applied to every page — this is the single most commonly missed one-click fix in PDF remediation.

tab-order-and-tagging.txt
Acrobat — set tab order on ALL pages
  View ▸ Show/Hide ▸ Side panels ▸ Page thumbnails
  Ctrl+A (select every thumbnail)
  Right-click ▸ Page Properties ▸ Tab Order
  ◉ Use Document Structure          ← writes /Tabs /S
  (doing this on page 1 only is the usual mistake)

Acrobat — tag a stray annotation
  Accessibility tags panel ▸ find the annotation on the page
  Options ▸ "Find" ▸ Unmarked annotations ▸ Search
  → "Tag element" for each one found
  Give it a meaningful tag: Annot, Link, or Form

Or mark it as decoration, if it truly carries no meaning:
  set the annotation's Artifact flag instead of tagging it.

How to fix

  1. Select every page thumbnail, open Page Properties ▸ Tab Order and choose “Use Document Structure” — this writes /Tabs /S to all pages at once.
  2. Run the Accessibility Tags panel’s “Find unmarked annotations” search to locate annotations that never made it into the tree.
  3. Tag each one with a meaningful element — Link for links, Form for widgets, Annot for the rest — and give it a description.
  4. Where an annotation carries no meaning (a decorative stamp, a registration mark), mark it as an artifact instead of tagging it.
  5. Tab through each page and confirm focus moves in reading order, not in the order objects were added to the file.

Review comments tagged in the wrong place

PDF/UA-2 WCAG 2.2 · 1.3.1 A EN 301 549

Markup annotations — sticky notes, highlights, strikeouts, freehand ink — are review artefacts that often survive into a published file. PDF/UA has a specific shape for them: the annotation must be tagged, it must sit inside an Annot structure element, and it needs a /Contents description saying what it is. Its popup, though, must stay out of the tree entirely — the popup is a duplicate of the note’s text, and tagging it makes a screen reader read every comment twice. The cheapest fix is usually not to tag them at all: if the comments were part of review and not part of the document, flatten or delete them before publishing.

Checks this covers: MARKUP_ANNOT_TAGGED, MARKUP_ANNOT_PARENT_ANNOT, MARKUP_ANNOT_DESCRIPTION, POPUP_IN_STRUCTURE — open any one for the full step-by-step fix.

Bad

A highlight with no description, a note tagged directly into a paragraph rather than inside an Annot, and its popup tagged as well.

markup-annots-bad.txt
<P>
  Revenue rose 8% this quarter.
  <Highlight-OBJR/>            <!-- not inside an Annot element -->
  <Text-OBJR/>                 <!-- sticky note, no /Contents -->
  <Popup-OBJR/>                <!-- popup must NOT be in the tree -->
</P>

/Annots [
  << /Subtype /Highlight >>                    <!-- no /Contents -->
  << /Subtype /Text /Contents (Check this) /Popup 22 0 R >>
  << /Subtype /Popup /Parent 21 0 R >>
]

Screen reader: "…rose 8% this quarter. Check this. Check this."

Good

Each markup annotation sits inside its own Annot element with a description; the popup is left out of the tree.

markup-annots-good.txt
<P>Revenue rose 8% this quarter.</P>

<Annot>
  <Highlight-OBJR/>
</Annot>
<Annot>
  <Text-OBJR/>
</Annot>
<!-- the Popup is deliberately absent from the structure tree -->

/Annots [
  << /Subtype /Highlight /Contents (Highlighted: revenue figure) >>
  << /Subtype /Text /Contents (Reviewer note: check this figure)
     /Popup 22 0 R >>
  << /Subtype /Popup /Parent 21 0 R >>   <!-- exists, but untagged -->
]

Screen reader: "…rose 8% this quarter.
                annotation, Reviewer note: check this figure"

Code

Decide first whether the comments belong in the published file at all — deleting them clears all four checks at once.

handling-comments.txt
Preferred: remove review comments before publishing
  Acrobat ▸ Comment tool ▸ select all ▸ Delete
  or  All tools ▸ Redact ▸ Sanitize document
      (removes comments, hidden text and metadata)

If the comments must stay (an annotated teaching copy):
  Comment tool ▸ open each annotation ▸ type a description
    into the note body — that populates /Contents
  Accessibility tags panel:
    wrap each annotation reference in an <Annot> element
    delete any <Popup> reference from the tree

Never: tag the popup. It duplicates the note's own text and
       causes every comment to be announced twice.

How to fix

  1. Decide whether the comments are part of the document. If they are review leftovers, delete them or run Sanitize Document — that clears all four checks at once.
  2. For comments that stay, give each one a /Contents description by typing into the note body in the Comment tool.
  3. In the tag tree, wrap each markup annotation reference in its own Annot element rather than dropping it into a paragraph.
  4. Delete any Popup reference from the structure tree — the popup must exist in the file but must not be tagged.
  5. Read the page aloud and confirm each comment is announced exactly once.

Media, file attachments, printer marks and deprecated types

PDF/UA-2 WCAG 2.2 · 1.1.1 A EN 301 549 Section 508

The remaining annotation types each fail in their own way, but they share a cause: content placed into the file by a tool rather than authored, and therefore never described. Embedded video and audio (Screen annotations) and 3D or rich media need a text alternative saying what they contain, exactly as an image does. File attachments need a description and a stated relationship, so a reader knows what the paperclip holds before opening it. Printer marks — crop marks, registration targets, colour bars — are production furniture and must be artifacts, never content. And several annotation subtypes were deprecated in PDF 2.0; a conforming file cannot use them at all.

Checks this covers: SCREEN_ANNOT_CONTENTS, MULTIMEDIA_ALT_DESCRIPTION, FILEATTACHMENT_METADATA, PRINTERMARK_ARTIFACT, ANNOT_DEPRECATED_TYPE — open any one for the full step-by-step fix.

Bad

A video with no description, an attachment called “file1”, printer marks tagged as content, and a deprecated Sound annotation.

media-annots-bad.txt
<Annot>
  <Screen-OBJR/>        <!-- embedded video, no /Contents -->
</Annot>

<< /Subtype /FileAttachment
   /FS << /F (file1.xlsx) >>      <!-- no /Desc, no /AFRelationship -->
>>

<Artifact? no --> <Annot><PrinterMark-OBJR/></Annot>
   <!-- crop marks tagged as real content: read out as an annotation -->

<< /Subtype /Sound >>   <!-- deprecated in PDF 2.0 -->
<< /Subtype /Movie >>   <!-- deprecated in PDF 2.0 -->

Good

Media and attachments are described, printer marks are artifacts, and deprecated types are replaced with their PDF 2.0 equivalents.

media-annots-good.txt
<Annot Alt="Product demonstration video, 3 minutes,
                captions included">
  <Screen-OBJR/>
</Annot>

<< /Subtype /FileAttachment
   /Contents (Q4 revenue workbook)
   /FS << /F (q4-revenue.xlsx)
          /UF (q4-revenue.xlsx)          <!-- Unicode filename -->
          /Desc (Source spreadsheet for the figures in table 3) >>
   /AFRelationship /Source >>            <!-- states the relationship -->

<!-- printer marks carry no meaning: mark as artifact, do not tag -->
<< /Subtype /PrinterMark /F 4 >>   (artifact, absent from the tree)

<!-- Sound and Movie replaced by /Screen with a media clip -->
<< /Subtype /Screen /Contents (Audio: welcome message, 40 seconds) >>

Code

Most of these are better solved by not embedding the object at all — a captioned video hosted on a page is more accessible than one embedded in a PDF.

media-and-attachments.txt
Embedded media
  Prefer linking to a captioned, described version online.
  If it must be embedded:
    Accessibility tags panel ▸ select the <Annot>
    Right-click ▸ Properties ▸ Alternate Text
    Describe what it shows AND state whether it has captions.

File attachments
  Acrobat ▸ Attachments panel ▸ right-click ▸ Edit Description
  Give a human description, not the filename.
  Ensure the filename is stored as Unicode (/UF), so
  non-ASCII names survive.

Printer marks
  These belong to print production, not the published PDF.
  Remove them, or set the annotation's Artifact flag.

Deprecated subtypes (PDF 2.0)
  /Sound and /Movie must be replaced with /Screen.
  Re-place the media through a current version of Acrobat.

How to fix

  1. Prefer linking to captioned, described media online over embedding it — an embedded player is harder to operate for everyone.
  2. Where media stays embedded, add alt text to its Annot that says what it contains and whether captions are available.
  3. Give every file attachment a human description and an /AFRelationship, and store the filename as Unicode.
  4. Remove printer marks from the published file, or flag them as artifacts so they never reach the tag tree.
  5. Replace deprecated Sound and Movie annotations with Screen by re-placing the media in a current version of Acrobat.

Recap

  • Links — the Link element must contain both the visible text and the annotation’s OBJR, and the link must have something to announce (2.4.4).
  • Shadowing — an ancestor with its own alt text replaces the link’s description; don’t nest a Link inside a described Figure.
  • Tab order — set /Tabs /S on every page, not just page one (2.4.3).
  • Comments — wrap each in an Annot with a description, and never tag the popup. Better still, remove review comments before publishing.
  • Media & attachments — describe what they contain; make printer marks artifacts and replace deprecated subtypes (1.1.1).

Annotations are the layer most likely to survive from an editing workflow into a published file. Sanitizing a document before release removes most of these findings outright, and is faster than tagging comments nobody intended to publish.