textbox
Marks an element as a single- or multi-line text input. Use <input type="text"> or <textarea> first — they handle every textbox behaviour for free. Reach for role="textbox" only when building a rich-text editor on a contenteditable element.
When to use
Use <input type="text">, <input type="email">, <input type="url">, <input type="tel">, or <textarea> — whichever matches the input semantics. Native handles selection, the caret, IME composition, form submission, autocomplete tokens, and validation, all of which are very hard to recreate.
role="textbox" is appropriate on one kind of element: a contenteditable div that hosts a rich-text editor. The role tells assistive tech to expose it as an editable region rather than a generic container. Set aria-multiline="true" if the editor accepts multiple lines.
If your “textbox” needs autocomplete suggestions, use role="combobox" on the input instead — textbox does not own a popup.
Common failures
role="textbox"applied to a<div>that is NOTcontenteditable. The role announces an editable field but typing does nothing.- Custom textboxes without a paired
<label for>oraria-label— the field has no accessible name. - Using
placeholderas the only label. Placeholder disappears on focus, fails contrast for many themes, and is not an accessible name. role="textbox"on a single-line contenteditable that does not strip pasted line breaks. Users paste content with newlines that bypass the visual constraint.- Missing
aria-multiline="true"on a multi-line contenteditable editor — screen readers announce it as a single-line input.
Example
<!-- Preferred -->
<label for="bio">Short bio</label>
<textarea id="bio" rows="4" maxlength="240"></textarea>
<!-- Rich-text editor -->
<label id="commentLabel">Comment</label>
<div
role="textbox"
contenteditable="true"
aria-labelledby="commentLabel"
aria-multiline="true"
></div>