Skip to content

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.
  • People who use a screen reader or a braille display, most of them blind.

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>
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>.

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.

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.

axe-core’s documentation of the rule

CORA’s fix guidance adapts content from accessibility-agents, under the MIT License: see its notice.