Lists must contain only li elements
Last updated:
Related Guides
Lists must not contain content elements other than li
In ul and ol, every content item must be inside an li element.
This issue appears in navigation menus, sidebars, FAQs, and article content.
It affects screen reader users who depend on list announcements and item counts to navigate.
Why It Matters
Screen readers announce the start of a list, the total number of items, and each item in order. If a list includes non-li content, assistive tech may skip items, misreport counts, or read content out of context.
Incorrect list structure also breaks hierarchy for nested lists, creating confusion for people with cognitive disabilities and anyone relying on consistent structure.
From a robustness standpoint, invalid HTML can cause inconsistent rendering across browsers and tools.
Common Causes
- Putting
<div>,<p>, or heading elements directly inside<ul>or<ol> - Placing a nested <ul>/<ol> directly inside a list without wrapping it in an
<li> - Mixing text nodes (loose text) or line breaks as list content
- Faking bullets with CSS or characters instead of semantic <ul>/<ol>/<li>
- Using
role="list"androle="listitem"when native list elements are available - Copy/paste from WYSIWYG editors that insert extra markup or comments inside lists
How to Fix
- Use the correct element:
- Use
<ul>for unordered items and<ol>for ordered items. - Use
<dl>only for term–description pairs, not general lists.
- Use
- Restrict children to allowed elements:
- Direct children of <ul>/<ol> must be
<li>elements. - Per HTML, only script-supporting elements (
<script>,<template>) may also appear; avoid others.
- Direct children of <ul>/<ol> must be
- Wrap all content in
<li>:- Move any paragraphs, headings, images, or nested lists inside a single
<li>per item. - For nested lists, place the nested <ul>/<ol> inside the related
<li>.
- Move any paragraphs, headings, images, or nested lists inside a single
- Keep structure meaningful:
- One logical item per
<li>. - Do not rely on
<br>or punctuation for list structure.
- One logical item per
- Style without breaking semantics:
- Use CSS (list-style-type, margin, padding) to control appearance. Avoid replacing
<li>with non-semantic elements styled as list items.
- Use CSS (list-style-type, margin, padding) to control appearance. Avoid replacing
- ARIA only when necessary:
- Prefer native <ul>/<ol>/<li>. If you must create a custom, non-HTML list, use
role="list"androle="listitem"and ensure correct order and counts (aria-posinset,aria-setsizewhen needed).
- Prefer native <ul>/<ol>/<li>. If you must create a custom, non-HTML list, use
WCAG alignment: 1.3.1 Info and Relationships; 4.1.1 Parsing; 4.1.2 Name, Role, Value (for custom lists).
How to Test
Keyboard
- Tab through interactive elements within the list to ensure order follows the visual/logical sequence of list items.
- Confirm no stray focus lands on non-item text inside the list.
Screen reader
- With NVDA/JAWS/VoiceOver, navigate to the list. Verify it announces “list” and the correct number of items.
- Move item by item. Check that all expected content is read within items, including nested lists announced correctly.
Mobile/touch
- With TalkBack/VoiceOver, swipe through the list and verify list context and counts are announced.
Code/dev tools
- Inspect the DOM. Ensure each <ul>/<ol> contains only
<li>(and optional <script>/<template>). - Run an automated check (axe, WAVE) and the W3C HTML validator to catch invalid children or stray text nodes.
Simple checklist
- Every list has the right element type (ul or ol).
- No direct children of ul/ol except li (and optional script/template).
- Nested lists are inside an li.
- One logical item per li.
- No fake bullets or line-break lists.
- Screen readers announce list count and items as expected.
Good Example
<p>Upcoming tasks</p>
<ul>
<li>Submit Q2 report</li>
<li>Schedule team retrospective
<ul>
<li>Collect feedback</li>
<li>Prepare agenda</li>
</ul>
</li>
<li>Update documentation</li>
</ul>Bad Example
<ul>
<h4>Submit Q2 report</h4>
<div>Schedule team retrospective</div>
<ul>
<li>Collect feedback</li>
<li>Prepare agenda</li>
</ul>
Final step: Update documentation
</ul>Quick Checklist
- Use ul/ol for lists; dl only for term–description pairs
- Only li as direct children of ul/ol
- Place nested lists inside the relevant li
- Move headings/paragraphs inside the li or outside the list
- Do not use
<br>, characters, or CSS alone to fake lists - Prefer native HTML over ARIA; add roles only for custom widgets
- Validate markup and verify correct list announcements with a screen reader