Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Use when applies to HTML documents with `<li>` elements. Also applies to custom ARIA lists where `role='listitem'` must be owned by `role='list'`. Common violations occur in templating systems where list markup is split across components or in CSS resets where developers use `<li>` for layout without proper list parents.
.claude/skills/thedaviddias-listitem/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-02 | ✗→✓ | ▲ Improved | 10% | 0% |
| case-04 | ✓→✗ | ▼ Worse | 35% | 0% |
| case-03 | ✓→✓ | = Same ✓ | 68% | 0% |
| case-01 | ✓→✓ | = Same ✓ | 43% | 0% |
| case-05 | ✓→✓ | = Same ✓ | 15% | 0% |
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.
<li> element must have a direct parent of <ul>, <ol>, or <menu><li> elements are invalid HTML per the HTML Living Standard<li> is inside a valid list containerrole='listitem' must be owned by a role='list' element per WAI-ARIA requirementsFind 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'.
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.
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 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.
For full implementation details, code examples, and framework-specific guidance, see references/rule.md.
Rule page: https://frontendchecklist.io/en/rules/accessibility/listitem
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-03 | pass→pass | 4,246 | 3,386 | -20% | 1 | 1 | 0% | 778 | 1,310 | +68% | 0 | 0 | — |
case-04 | pass→fail | 6,831 | 6,094 | -11% | 1 | 1 | 0% | 1,402 | 1,886 | +35% | 0 | 0 | — |
case-01 | pass→pass | 7,438 | 7,420 | -0% | 1 | 1 | 0% | 1,413 | 2,025 | +43% | 0 | 0 | — |
case-02 | fail→pass | 7,902 | 6,041 | -24% | 1 | 1 | 0% | 1,621 | 1,781 | +10% | 0 | 0 | — |
case-05 | pass→pass | 8,052 | 6,178 | -23% | 1 | 1 | 0% | 1,528 | 1,757 | +15% | 0 | 0 | — |
case-06 | pass→pass | 5,314 | 2,596 | -51% | 1 | 1 | 0% | 898 | 1,061 | +18% | 0 | 0 | — |
case-07 | pass→pass | 12,355 | 9,588 | -22% | 1 | 1 | 0% | 2,161 | 2,411 | +12% | 0 | 0 | — |
case-08 | pass→pass | 3,307 | 3,497 | +6% | 1 | 1 | 0% | 583 | 1,320 | +126% | 0 | 0 | — |
case-09 | pass→pass | 3,943 | 3,514 | -11% | 1 | 1 | 0% | 755 | 1,273 | +69% | 0 | 0 | — |
case-10 | pass→pass | 10,484 | 6,989 | -33% | 1 | 1 | 0% | 2,001 | 1,962 | -2% | 0 | 0 | — |
case-11 | pass→pass | 5,588 | 4,492 | -20% | 1 | 1 | 0% | 921 | 1,456 | +58% | 0 | 0 | — |
case-12 | pass→pass | 7,223 | 5,131 | -29% | 1 | 1 | 0% | 1,369 | 1,538 | +12% | 0 | 0 | — |
case-13 | pass→pass | 5,076 | 3,258 | -36% | 1 | 1 | 0% | 926 | 1,251 | +35% | 0 | 0 | — |
case-14 | pass→pass | 5,939 | 4,463 | -25% | 1 | 1 | 0% | 1,074 | 1,521 | +42% | 0 | 0 | — |
case-15 | pass→pass | 15,116 | 10,855 | -28% | 1 | 1 | 0% | 2,584 | 2,716 | +5% | 0 | 0 | — |
case-16 | pass→pass | 3,758 | 5,975 | +59% | 1 | 1 | 0% | 737 | 1,820 | +147% | 0 | 0 | — |
case-17 | pass→pass | 6,513 | 4,798 | -26% | 1 | 1 | 0% | 1,261 | 1,539 | +22% | 0 | 0 | — |
case-18 | pass→pass | 7,669 | 5,308 | -31% | 1 | 1 | 0% | 1,466 | 1,618 | +10% | 0 | 0 | — |
case-19 | pass→pass | 3,350 | 4,413 | +32% | 1 | 1 | 0% | 614 | 1,354 | +121% | 0 | 0 | — |
case-20 | fail→fail | 11,166 | 8,998 | -19% | 1 | 1 | 0% | 2,074 | 2,496 | +20% | 0 | 0 | — |
case-21 | pass→pass | 6,524 | 5,635 | -14% | 1 | 1 | 0% | 1,201 | 1,619 | +35% | 0 | 0 | — |
case-22 | pass→pass | 13,322 | 11,213 | -16% | 1 | 1 | 0% | 2,505 | 2,640 | +5% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of 0 percentage points is the difference between those two pass rates over the 22 comparable cases. 1 case got worse with the skill loaded, and it is included in that figure.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.