listitem-parent-valid
List items must be inside a list container
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_OVERRIDDENwhen the parent is a <ul>, <ol> or <menu> whose explicit role replaces list (<ul role="tablist">),LISTITEM_INVALID_PARENTotherwise. 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: withLIST_ROLE_OVERRIDDEN, the parent's role.parentElementis a stable contract, unlike the rest ofdata.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
<ul><li>Apple</li></ul>
<li> is inside a <ul>.
<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
- Inspect the <li> the report names and note its parent, which is not a <ul>, <ol>, <menu> or an element with role list.
- Look at whether the page shows it as an item of a list, with a bullet or number, next to other items.
- 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
- Inspect the <li> the report names and note the role its <ul>, <ol> or <menu> parent has in place of list.
- Look at whether the page shows it as an item of a list, with a bullet or number, next to other items.
- 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).