About This HTML Issue
The textbox ARIA role identifies an element that allows free-form text input. While it can technically be applied to elements using contenteditable, it should not be placed on elements that already carry strong semantic meaning, such as <li>. A list item is expected to be a child of <ul>, <ol>, or <menu>, and its implicit listitem role communicates its purpose within a list structure to assistive technologies. Assigning role="textbox" to an <li> overrides this semantic, confusing screen readers and other assistive tools about whether the element is a list item or a text input field.
This is problematic for several reasons:
-
Accessibility: Screen readers rely on roles to convey the purpose of elements to users. An
<li>withrole="textbox"sends mixed signals — it exists within a list structure but announces itself as a text input. -
Standards compliance: The ARIA in HTML specification restricts which roles can be applied to specific elements. The
lielement does not allow thetextboxrole, which is why the W3C validator flags this as an error. - Browser behavior: Browsers may handle the conflicting semantics unpredictably, leading to inconsistent experiences across different user agents.
The best approach is to use native HTML form elements whenever possible. The <input type="text"> element handles single-line text input, and the <textarea> element handles multi-line input. These native elements come with built-in keyboard support, focus management, and form submission behavior — none of which you get for free with a role="textbox" on a non-form element.
If you genuinely need an editable area inside a list and cannot use native form elements, nest a <div> or <span> with role="textbox" inside the <li> rather than placing the role on the <li> itself.
Examples
❌ Incorrect: role="textbox" on an li element
<ul>
<li role="textbox" contenteditable="true">Edit this item</li>
<li role="textbox" contenteditable="true">Edit this item too</li>
</ul>
This triggers the validator error because textbox is not a valid role for <li>.
✅ Fix: Use native form elements
The simplest and most robust fix is to use standard form controls:
<ul>
<li>
<label for="item1">Item 1:</label>
<input type="text" id="item1" value="Edit this item">
</li>
<li>
<label for="item2">Item 2:</label>
<input type="text" id="item2" value="Edit this item too">
</li>
</ul>
For multi-line input, use <textarea>:
<ul>
<li>
<label for="note1">Note:</label>
<textarea id="note1">Edit this content</textarea>
</li>
</ul>
✅ Fix: Nest a div with role="textbox" inside the li
If you need a contenteditable area and cannot use native form elements, place the textbox role on a nested element:
<ul>
<li>
<div id="label1">Item 1:</div>
<div
role="textbox"
contenteditable="true"
aria-labelledby="label1"
aria-placeholder="Enter text">
Edit this item
</div>
</li>
</ul>
This preserves the <li> element’s implicit listitem role while correctly assigning the textbox role to a semantically neutral <div>.
✅ Fix: Remove the list structure entirely
If the items aren’t truly a list, consider dropping the <ul>/<li> structure altogether:
<div id="zipLabel">Enter your five-digit zipcode</div>
<div
role="textbox"
contenteditable="true"
aria-placeholder="5-digit zipcode"
aria-labelledby="zipLabel">
</div>
In every case, prefer native <input> and <textarea> elements over role="textbox" with contenteditable. Native elements provide accessible behavior by default, including keyboard interaction, form validation, and proper focus management, without requiring additional ARIA attributes or JavaScript.
Find issues like this automatically
Rocket Validator scans thousands of pages in seconds, detecting HTML issues across your entire site.
Learn more: