Skip to main content
Beta: Front-End Checklist is currently in beta. Some issues are still being fixed. Thanks for your patience.

Place list items within list containers

List item elements (li) must always be direct children of a list container (ul, ol, or menu) to maintain valid HTML structure and correct screen reader announcements.

Utilities
Quick take
Typical fix time 5 min
  • Every `<li>` element must have a direct parent of `<ul>`, `<ol>`, or `<menu>`
  • Orphan `<li>` elements are invalid HTML per the HTML Living Standard
  • Screen readers announce list type and item count (e.g., 'list, 3 items') only when `<li>` is inside a valid list container
  • Similarly, `role='listitem'` must be owned by a `role='list'` element per WAI-ARIA requirements
Why it matters: When a `<li>` element exists outside a list container, screen readers lose the ability to announce critical context: NVDA and JAWS will not say 'list of 5 items' or 'item 2 of 5' because there is no list context. VoiceOver may announce the orphan `<li>` as plain text without any group context, stripping users of the structural information that helps them understand how many items exist and where they are in the list.

Rule Details

List items such as <li> (opens in new tab) are semantic elements that must exist within a list context. The HTML Living Standard (opens in new tab) and the ARIA listitem role reference (opens in new tab) both require that ownership relationship, so using them outside a <ul>, <ol>, or <menu> parent breaks the accessibility tree.

Code Example

<!-- ❌ Incorrect: orphan <li> inside a <div> — invalid HTML -->
<div>
  <li>Contact us</li>
  <li>About us</li>
</div>
 
<!-- ✅ Correct: wrapped in <ul> for unordered items -->
<ul>
  <li>Contact us</li>
  <li>About us</li>
</ul>
 
<!-- ✅ Correct: <ol> for sequentially ordered steps -->
<ol>
  <li>Sign up</li>
  <li>Confirm email</li>
  <li>Start browsing</li>
</ol>
 
<!-- ✅ Correct: navigation using list structure -->
<nav aria-label="Main navigation">
  <ul>
    <li><a href="/">Home</a></li>
    <li><a href="/about">About</a></li>
    <li><a href="/contact">Contact</a></li>
  </ul>
</nav>
 
<!-- ⚠️ Note: list-style: none may remove list semantics in Safari/VoiceOver -->
<ul style="list-style: none;" role="list">
  <li><a href="/home">Home</a></li>
</ul>

Why It Matters

  • Semantic Integrity: The <li> element represents membership in a list — without the list parent, that meaning is lost.
  • Item Count Announcement: Screen readers announce "list, 3 items" only when a valid parent list exists; orphan items get no count.
  • List Type Context: NVDA distinguishes "bullet list" from "numbered list" based on the parent element type.
  • HTML Validity: Invalid nesting can cause unpredictable rendering differences across browsers and parsing failures in XML-based tools.

Exceptions

  • Simple data tables can sometimes fail more from missing header relationships than from missing enhancements such as captions or mobile wrappers, so prioritize the strongest semantic issue.
  • Do not convert layout structures into data-table markup just to satisfy a rule; the correct fix may be to remove table semantics entirely.
  • When several table-accessibility issues overlap, resolve the header-cell relationship first because downstream announcements depend on it.

Standards

  • Align the implementation with HTML Living Standard: The li element and verify the rendered experience, not only the source code.
  • Align the implementation with WAI-ARIA 1.2: listitem Role and verify the rendered experience, not only the source code.
  • Align the implementation with MDN: &lt;li&gt; element and verify the rendered experience, not only the source code.

Verification

Automated Checks

  • Inspect the browser accessibility tree or accessibility pane for the relevant element, role, or accessible name.
  • Run an automated accessibility checker such as axe or Lighthouse where applicable.

Manual Checks

  • Test the affected UI with keyboard-only navigation and confirm the rule holds in the rendered experience.
  • Re-test one representative user flow with a screen reader if this rule affects a key interaction.

Use with AI

Copy these prompts to use with your AI assistant, or install the MCP server to use directly from Claude, Cursor, or Windsurf.

Check

Verify implementation

Find all `<li>` elements in the DOM. For each, check that its direct parent element is `<ul>`, `<ol>`, or `<menu>`. Flag any `<li>` whose parent is `<div>`, `<section>`, `<nav>`, `<span>`, or any element other than those three. Also check `role='listitem'` elements to ensure their closest ancestor with a list-related role is `role='list'`.

Fix

Auto-fix issues

For each orphan `<li>`: (1) Wrap it and any sibling `<li>` elements in the appropriate list container — use `<ul>` for unordered items or `<ol>` for sequentially ordered items. (2) If the `<li>` was being used purely for styling (e.g., a bullet point visual), replace it with a `<div>` or `<p>` and apply the visual style via CSS. (3) If inside a navigation element, ensure `<nav><ul><li>` nesting is maintained.

Explain

Learn more

The HTML Living Standard specifies that `<li>` elements are only valid as children of `<ul>`, `<ol>`, or `<menu>`. This is a structural requirement, not a style preference. Screen readers use the list container to announce the list type ('bullet list' vs 'numbered list') and the total item count. Without the container, this context is lost entirely. Additionally, when `list-style: none` is applied to a `<ul>`, some browsers strip the list semantics — if this is intentional (e.g., a navigation menu), add `role='list'` to the `<ul>` to restore list semantics for screen readers.

Review

Code review

Review the rendered markup and interactive states that affect Place list items within list containers. Flag exact elements, roles, labels, focus behavior, or keyboard interactions that violate the rule, and note how to verify the fix with browser accessibility tooling or assistive tech.

Sources

References used to support the guidance in this rule.

Further Reading

Tools and supplementary material for exploring the topic in more depth.

axe DevTools
deque.comTool

Rules that often go hand-in-hand with this one.

Ensure ARIA roles contain required child roles

Elements with certain ARIA roles must contain the required child roles or the widget structure will be broken for assistive technologies.

Accessibility
Use correct list structure

Lists (ul, ol) should only contain list item elements (li) to ensure they are correctly interpreted by assistive technology.

Accessibility
Use correct definition list structure

Definition lists (&lt;dl&gt;) must only contain valid &lt;dt&gt; and &lt;dd&gt; elements.

Accessibility
Ensure ARIA roles are contained by required parent roles

Checks that elements with certain roles have required parent roles

Accessibility

Was this rule helpful?

Your feedback helps improve rule quality. This stays internal for now.

Loading feedback...
0 / 385