Matterhorn 14-007 · PDF/UA-1 UA1:7.4.4-3

H and H1–H6 in the same document: two heading models at once

Blocker Checkpoint 14: Headings WCAG 1.3.1 (A)

A document must commit to one heading model: strong structure (H, levelled by nesting) or weak structure (H1–H6). Mixing them makes the level of any given heading ambiguous.

The condition, as the protocol states it. “Document uses both <H> and <H#> tags.”

Matterhorn Protocol 1.1, checkpoint 14, index 14-007, section UA1:7.4.4-3. Software can decide this one on its own.

What a screen reader actually does

Heading levels are computed differently by different readers; the outline is unreliable.

The two models

ISO 32000-1 defines heading level twice, and they are alternatives rather than layers.

Weak structure — H1 to H6. The level is in the tag name. The structure tree is flat, the outline is read straight off the element types, and the nesting of Sect elements is irrelevant to it.

/Document
├── /H1  "Annual report"
├── /H2  "Results"
└── /H3  "Revenue"

Strong structure — H inside nested Sect. The tag is always H; the level is the depth of Sect nesting around it.

/Document
└── /Sect                 ← depth 1
    ├── /H   "Annual report"      = level 1
    └── /Sect             ← depth 2
        ├── /H  "Results"         = level 2
        └── /Sect         ← depth 3
            └── /H  "Revenue"     = level 3

Both are legal PDF. PDF/UA-1 clause 7.4.4 requires a document to use one of them, not both.

Why mixing them has no defined answer

Consider a file with an H1, then an H, then an H2. What level is the H?

There is no answer the specification supplies. If the reader is applying strong structure it computes the level from Sect depth — and in a document written for weak structure there is often no Sect nesting at all, so the computed depth is 1, and a heading that sits visually between an H1 and an H2 is announced as a sibling of the H1. If the reader is applying weak structure it has a tag with no number in it and falls back to a default, which differs by implementation.

The outcome is not a wrong level; it is a level that depends on which software opened the file. That is the reason this is a blocker rather than a warning. Everything else in a heading outline can be checked against an intention; this cannot, because the intention is genuinely ambiguous in the file.

Where it comes from

Editing a file that was tagged by a different tool. Somebody adds a heading in Acrobat’s Tags panel, and the panel’s New Tag dialog offers Heading as well as Heading Level 1 through 6. Choosing Heading inserts an H. Everything else in the document is numbered, and one element is not.

Merging documents. Two PDFs produced by different pipelines, combined with File → Combine. The structure trees are concatenated; nothing reconciles the heading models.

Libraries with strong-structure defaults. A handful of PDF generators emit H inside Sect because it is the more correct model. A file assembled from pages produced by two different libraries carries both.

Hand-editing XML-ish structure. Anyone working directly on the structure tree hits this eventually, because H looks like the generic case and H2 looks like a specialisation of it. They are not related that way.

How to check it free

Acrobat Pro. Open the Tags panel and read the element types down the tree. An H appears as Heading; the numbered ones appear as Heading 1, Heading 2 and so on. Seeing both words in one document is the whole test.

veraPDF reports it against clause 7.4.4 and names the offending elements.

PAC reports it under Logical Structure → Headings.

How to fix it free, in Acrobat Pro

Decide which model the document is using — in practice, whichever one the majority of headings already use — and convert the minority.

Converting H to a number:

  1. Tags panel, find each Heading element.
  2. Right-click → PropertiesTag tab → Type.
  3. Choose the numbered level it should have, based on the headings around it rather than on its Sect depth.

Converting the other way — numbered to H — requires building the Sect nesting to carry the level, which is substantially more work and almost never the right direction. If the document has ten H2s and one H, change the one.

Where Taggart differs

Taggart reports which model the document is predominantly in, with counts, rather than reporting only that the two are mixed:

41 headings use the numbered model (H1–H6), 2 use the untyped H. The untyped headings are at page 7 and page 12.

That is the information the repair needs, and it is what tells you this is a two-element fix rather than a document-wide decision.

The repair itself is part of heading-levels, and Taggart infers the level for each H from its position in the outline — the level of the nearest preceding numbered heading, plus one if the element is nested inside it, the same otherwise — rather than from Sect depth, because in a weak-structure document the Sect depth carries no information. The inferred level is shown before it is applied, since an inference about document shape is exactly the kind of thing that should be looked at rather than trusted.

How Taggart handles it

Taggart detects this condition automatically. It is reported as a blocker, with the page, the structure path and the object id of every occurrence.

The fix is Repair heading levels. It is mechanical, so “Fix All Safe” applies it in bulk with a diff and a single undo.

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

Which model should I use?

H1–H6 — weak structure — unless you have a specific reason not to. Every mainstream screen reader supports it, every authoring tool emits it, and the level is readable without walking the tree. Strong structure is elegant and almost nobody implements it well.

What is the H tag actually for?

Strong structure. In that model a heading is just H, and its level comes from how deeply its containing Sect elements are nested: an H inside one Sect is level 1, inside two is level 2. It is the more principled design — the level is a fact about the document's shape rather than a number somebody typed — and it requires the Sect nesting to be correct and complete.

Is a single H in a document of H1–H6 really a failure?

Yes. One is enough. The condition is about the document committing to a model, and a document containing both has not.

Will a screen reader actually get this wrong?

It will produce something, and readers differ on what. Some announce a bare H as level 1, some as level 2, some compute it from Sect depth and get a number that contradicts the numbered headings around it. The failure mode is not silence, it is an outline the user cannot trust.

Where this sits in the standards

Standards this condition maps to
StandardReference
Matterhorn Protocol 1.1 Checkpoint 14 (Headings), index 14-007
PDF/UA-1 (ISO 14289-1) Clause 7.4.4-3
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.

Other conditions in checkpoint 14

Checkpoint 14 covers headings. These are its other failure conditions; the ones without a link are in the rule set but do not have a written page yet.

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.

Check a PDF free

Verified against a real document on . Last updated .