Lists need to hold only list items
- Rule:
axe/list - Checks: <ul> and <ol> must only directly contain <li>, <script> or <template> elements
- WCAG: 1.3.1
- Fix class:
mechanical: A fix needs no authored text or visual decision.
Who it affects
Section titled “Who it affects”- People who use a screen reader or a braille display, most of them blind.
How to fix it
Section titled “How to fix it”The items are wrapped in a <div> or a <span> inside the list
Section titled “The items are wrapped in a <div> or a <span> inside the list”Make each item an <li> that is a direct child of the <ul> or <ol>. Move any wrapper inside the <li>, or style the <li> itself.
<ul class="plans"> <li><div class="card">Starter plan</div></li> <li><div class="card">Team plan</div></li></ul>A nested list is a direct child of the outer list
Section titled “A nested list is a direct child of the outer list”Move the nested list inside the <li> it belongs to.
<ul> <li> Fruit <ul> <li>Apples</li> <li>Pears</li> </ul> </li></ul>The list holds a heading, text or a link directly
Section titled “The list holds a heading, text or a link directly”Put headings and introductory text before the list, and wrap each link in its own <li>.
Fixes that fail
Section titled “Fixes that fail”Adding role="none" or role="presentation" to the list
Section titled “Adding role="none" or role="presentation" to the list”axe stops checking it, but screen readers no longer announce a list or how many items it has.
In React
Section titled “In React”The part of the fix that differs in React, in its syntax. The rest of the guidance holds.
An item component returns a <div>, or wraps its <li> in another element
Section titled “An item component returns a <div>, or wraps its <li> in another element”Make the <li> the root element the item component returns, so that every child of the list is a list item.
function PlanItem({ plan }) { return <li className="plan">{plan.name}</li>;}
function PlanList({ plans }) { return ( <ul> {plans.map((plan) => ( <PlanItem key={plan.id} plan={plan} /> ))} </ul> );}A <div> wraps each mapped item only to hold its key
Section titled “A <div> wraps each mapped item only to hold its key”Put the key on the item component or on the <li>. If each item renders more than one <li>, return them in a <Fragment key={…}>, which adds no element.
More on the rule
Section titled “More on the rule”axe-core’s documentation of the rule
CORA’s fix guidance adapts content from accessibility-agents, under the MIT License: see its notice.