Matterhorn 09-005 · PDF/UA-1 UA1:7.2-1

Broken list structure: LI outside L, LBody missing

Blocker Checkpoint 09: Appropriate Tags WCAG 1.3.1 (A)

The list grammar is broken: an LI outside an L, an Lbl or LBody outside an LI, a list item with no LBody.

The condition, as the protocol states it. “A list-related structure element is used in a way that does not conform to Table 336 in ISO 32000-1.”

Matterhorn Protocol 1.1, checkpoint 09, index 09-005, section UA1:7.2-1. Software can decide this one on its own.

What a screen reader actually does

The reader does not announce "list of N items" and cannot navigate item to item.

The grammar

ISO 32000-1, Table 336:

L
├── Caption          optional, first
└── LI
    ├── Lbl          optional — the bullet or number
    └── LBody        the item's content
        └── L        a nested list goes here

Four element types, one nesting rule each. Condition 09-005 is any departure from it.

The departures that actually occur:

Content directly in the LI. By far the most common. An auto-tagger creates L → LI → P and skips LBody entirely.

LI outside an L. Usually a list item that was dragged out of its list while somebody was fixing reading order.

A nested L as a sibling of LBody rather than inside it. Legal-looking, and wrong: the sub-list is then not part of the item it belongs to.

Lbl outside an LI. A bullet that got separated from its item.

A P between two LI elements.

What the reader does

A screen reader builds a list model the same way it builds a table model: it needs valid structure before it will offer list behaviour at all.

With correct structure, NVDA announces “list with 7 items”, lets I move item to item, and announces “3 of 7” as you go. The Lbl is consumed as position information rather than read aloud, so you do not hear “black circle” seven times.

With broken structure the behaviour degrades unpredictably. Content inside an LI with no LBody is often read, but the item count goes wrong or the list is not announced as a list at all. Items outside their L are read as ordinary paragraphs.

The user’s loss is the same as with headings: they cannot tell how much is coming, and they cannot skip it.

How to find it free

Acrobat’s Tags panel. Expand the <L> and read the nesting. You are looking for L → LI → Lbl and L → LI → LBody. Anything shallower is this condition.

veraPDF: reports it under clause 7.2 with the offending element.

A screen reader: if the document has visible bullets and NVDA does not say “list”, something is wrong — either the grammar (this condition) or no list structure at all (16-003).

How to fix it free, in Acrobat Pro

Tedious but entirely possible.

  1. Open the Tags panel and expand the <L>.
  2. For each <LI> whose content is a direct <P>:
    • right-click the <LI>New Tag → type LBody;
    • drag the <P> into the new <LBody>.
  3. For an <LI> sitting outside its <L>: drag it back in.
  4. For a nested list in the wrong place: drag the inner <L> into the parent item’s <LBody>.
  5. Set the numbering on the <L>: right-click → PropertiesAttributes → add ListNumbering with Decimal, UpperRoman, LowerRoman, UpperAlpha or LowerAlpha. That is 16-001.

On a twenty-item list this is roughly forty drag operations.

Upstream is not a close call here. A list built with Word’s or InDesign’s list feature — the actual list style, not typed bullets — exports as complete L/LI/Lbl/LBody structure with ListNumbering already set. If your source has typed bullets, converting them to a real list style takes a minute and fixes every list in the document at once.

Where Taggart differs

Taggart validates the grammar and names the specific violation, rather than reporting “list problem”:

<LI> has no <LBody> child; every list item needs a body.

and

<LI> appears inside <Div> but the list structure grammar (ISO 32000-1, Table 336) requires it to be inside <L>.

Building missing structure is a semantic claim — these paragraphs form one list — so Taggart requires you to confirm the grouping. Given the groups, it constructs the full L/LI/LBody tree, moves each paragraph’s content into its LBody rather than copying it, splices the new <L> in where the first item was, and infers ListNumbering from the label text.

Setting ListNumbering on a list that already has valid structure is mechanical and ships in “Fix All Safe”.

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 Build list structure. It changes what the document means, so Taggart proposes it and waits for your approval rather than applying it unattended.

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

Can an LI contain content directly?

No. An LI contains an optional Lbl and an LBody, and the content goes in the LBody. Putting a paragraph straight into the LI is the single most common list defect, and it is what this condition catches.

How do I nest a list?

The nested L goes inside the parent item's LBody — not inside the LI directly, and not as a sibling of it. LBody is the item's content, and a sub-list is part of that content.

Is Lbl required?

Not by the grammar. But if the bullet or number is painted on the page it has to live somewhere, and Lbl is the only place that keeps it out of the middle of the item's text. If the marker is generated by the viewer rather than drawn, no Lbl is needed.

What can an L contain besides LI?

A Caption, as the first child. Nothing else. A P sitting between two LI elements is a failure — it is either an item that lost its wrapper, or content that belongs outside the list.

Where this sits in the standards

Standards this condition maps to
StandardReference
Matterhorn Protocol 1.1 Checkpoint 09 (Appropriate Tags), index 09-005
PDF/UA-1 (ISO 14289-1) Clause 7.2-1
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 09

Checkpoint 09 covers appropriate tags. 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 .