listitem-parent-valid

List items must be inside a list container

automaticWCAG 1.3.1 (A)confidence: highseverity: seriousperceivable

Checks that <li> elements are contained by <ul>, <ol>, <menu>, or an element with role="list".

Applies to. Applies to <li> elements that have a parent element.

Expectation. The parent is <ul>/<ol>/<menu> with no role override (all three have the implicit role list), or an element with an explicit role of "list", "directory" (deprecated, but a required parent of listitem in WAI-ARIA 1.2), "presentation", or "none". An <li> used outside a real list container (e.g. as a generic flex/grid item under a <div>) is not exposed as a list item to assistive technologies. It FAILS where the page still draws the <li> as a list item (display list-item with a marker): an item a reader sees that the markup puts in no list, a relationship not programmatically determinable (SC 1.3.1). An <li> drawn with no marker, as a plain layout box, shows no list, so the broken content model is reported at CANTTELL (H48 is only a sufficient technique) for a person to say whether it reads as a list. jsdom does not resolve the list-style shorthand, so there list-style: none set that way still reads as a marker.

What a finding reports.

  • reasonCode: LIST_ROLE_OVERRIDDEN when the parent is a <ul>, <ol> or <menu> whose explicit role replaces list (<ul role="tablist">), LISTITEM_INVALID_PARENT otherwise. Both fail where the <li> is drawn as a list item, and are asked about where it is not.
  • parentElement: the tag name of the <li>'s parent, the container it is in instead of a list.
  • parentRole: with LIST_ROLE_OVERRIDDEN, the parent's role.
  • parentElement is a stable contract, unlike the rest of data.details.

These data.details fields help to read and reproduce a finding. Apart from reasonCode and the few fields Output schema names as stable, they are not a stable contract: a field may be renamed or dropped in a minor release, so don’t build on them.

Examples

pass
<ul>
<li>Apple</li>
</ul>

<li> is inside a <ul>.

fail
<div>
<li>Date</li>
</div>

<li> has no <ul>/<ol>/role="list" ancestor, yet the browser draws it with a bullet: the page shows a list item the markup leaves in no list.

How to check

When this rule can’t decide, it reports cantTell and leaves the question to a person. Each question it can ask is listed here under its reason code, with the steps to answer it. A finding carries the same steps as howToCheck, in the scan’s language. See Output schema.

LISTITEM_INVALID_PARENT

  1. Inspect the <li> the report names and note its parent, which is not a <ul>, <ol>, <menu> or an element with role list.
  2. Look at whether the page shows it as an item of a list, with a bullet or number, next to other items.
  3. With a screen reader, read the content and note whether a list and its number of items are announced.

Pass. The element is not shown as an item of a list, so no list the page shows is missing from the markup. Still fix the markup: HTML allows an <li> only in a list.

Fail. The page shows the element as an item of a list, but the markup puts it in no list, so that relationship is not programmatically determinable (WCAG 1.3.1).

LIST_ROLE_OVERRIDDEN

  1. Inspect the <li> the report names and note the role its <ul>, <ol> or <menu> parent has in place of list.
  2. Look at whether the page shows it as an item of a list, with a bullet or number, next to other items.
  3. With a screen reader, read the content and note whether a list and its number of items are announced.

Pass. The element is not shown as an item of a list, so no list the page shows is missing from the markup. Still fix the markup: HTML allows an <li> only in a list.

Fail. The page shows the element as an item of a list, but the markup puts it in no list, so that relationship is not programmatically determinable (WCAG 1.3.1).

View source