Structure and landmarks Rule

List items must sit inside a list listitem

An li is only a list item when its parent is a ul, ol or menu. Put li elements straight into a div or a section and most screen readers stop treating them as a list: no item count, no jumping between items, sometimes no bullets. It usually happens when a template renders the items but loses the wrapper.

Websight reports this as <li> elements must be contained in a <ul> or <ol>

Who it affects

A student who is blind, checking the university library's opening hours hears seven lines of text with no list context, so cannot tell whether term-time and vacation hours are separate groups.

Someone who relies on a screen reader's list navigation (the L key in NVDA) finds nothing, because there is no list to find.

Someone using a reading tool that reformats the page sees the hours run together into one block.

Broken versus fixed

Both examples are live and rendered in a sandboxed frame. The broken one is deliberately broken.

Broken

Browsers draw the bullets anyway, so it looks fine. A screen reader announces the lines with no list, no count and no way to jump between them.

Fixed

Announced: list, 3 items, then each item in turn. Only the wrapper changed.

Show the markup behind both examples
Broken
<style>body{font-family:system-ui;margin:0;padding:16px}.hours{margin:4px 0 0;padding-left:22px}li{margin:2px 0}</style>
<p style="margin:0"><strong>Main library, term time</strong></p>
<div class="hours">
  <li>Monday to Friday, 8am to 10pm</li>
  <li>Saturday, 9am to 6pm</li>
  <li>Sunday, 11am to 6pm</li>
</div>
Fixed
<style>body{font-family:system-ui;margin:0;padding:16px}.hours{margin:4px 0 0;padding-left:22px}li{margin:2px 0}</style>
<p style="margin:0"><strong>Main library, term time</strong></p>
<ul class="hours">
  <li>Monday to Friday, 8am to 10pm</li>
  <li>Saturday, 9am to 6pm</li>
  <li>Sunday, 11am to 6pm</li>
</ul>

Test it by hand in two minutes

  1. Right click a bullet point, choose Inspect, and look at the parent of the li. It should be a ul or an ol, not a div or section.
  2. With NVDA running, press L to jump to the next list. If the bullets on screen are never reached, they are not a list.
  3. Open the component or template that outputs the items. The wrapper is often rendered in a different file, or only under some condition, and goes missing.

The fix

Before
<div class="hours">
  <li>Monday to Friday, 8am to 10pm</li>
  <li>Saturday, 9am to 6pm</li>
</div>
After
<ul class="hours">
  <li>Monday to Friday, 8am to 10pm</li>
  <li>Saturday, 9am to 6pm</li>
</ul>

Change the wrapper, not the items. Use ol instead if the order carries meaning.

One line that is not a list

Before
<section>
  <li>Open now</li>
</section>
After
<section>
  <p>Open now</p>
</section>

A single line on its own is not a list. Use a paragraph.

Items split across two wrappers

Before
<div><li>Term time, 8am to 10pm</li></div>
<div><li>Vacation, 9am to 5pm</li></div>
After
<ul>
  <li>Term time, 8am to 10pm</li>
  <li>Vacation, 9am to 5pm</li>
</ul>

If the items belong together, put them in one list.

Common mistakes

  • Adding role="list" to the div instead of using a ul, when a ul would do.
  • Leaving the li where it is and hiding the bullets with CSS, hoping nobody notices.
  • Using li as a generic row element in a grid or card layout.
  • Putting li elements directly inside a nav element with no ul.

WCAG criteria this rule maps to

axe-core tags this rule as WCAG 2.2 level A. It is one of the checks for:

The scanner can see an li whose parent is not a ul, ol or menu, or an element with role list. It cannot tell whether a set of lines that are not li elements at all should have been a list. Automated tools find only part of the accessibility problems on a page; a pass on this rule is not a pass on the criterion.

Scan your own page for this and 63 other checks

Open any page in Chrome, click Websight, and get a score out of 100 with every issue explained and a draft fix snippet per element.

Add Websight to Chrome

Free scans, no account, nothing leaves your computer. Automated tools find only part of the problems; the extension says so on every report.