aria-multiline
Indicates whether a text box accepts multiple lines of input or only a single line. Essential for custom text widgets built with ARIA roles.
Overview
The aria-multiline attribute indicates whether a textbox accepts multiple lines of input or only a single line. This is important for assistive technologies to convey the expected behavior to users.
Native HTML elements like <input type="text"> and <textarea> automatically communicate this information—you only need aria-multiline for custom ARIA textbox widgets.
When to Use
Only use aria-multiline on elements with role="textbox". Native inputs and textareas don't need this attribute.
Live Demo: Single-Line vs Multi-Line
Press Enter: nothing happens (single-line)
Press Enter: new line (1 line)
Screen reader: Single-line announces as "edit text". Multi-line announces as "edit text, multi-line" indicating multiple lines are expected.
Attribute Values
trueThe textbox accepts multiple lines of input. Users can press Enter to create new lines. Similar to a <textarea>.
false(default)The textbox accepts only a single line of input. Similar to <input type="text">. This is the default when the attribute is absent.
Code Examples
Basic Usage
<!-- Basic aria-multiline usage -->
<!-- Single-line text input (default) -->
<div
role="textbox"
aria-multiline="false"
aria-label="Username"
contenteditable="true"
tabindex="0"
>
</div>
<!-- Screen reader: "Username, edit text" -->
<!-- Multi-line text area -->
<div
role="textbox"
aria-multiline="true"
aria-label="Message"
contenteditable="true"
tabindex="0"
>
</div>
<!-- Screen reader: "Message, edit text, multi-line" -->Native vs Custom Elements
<!-- aria-multiline vs Native HTML Elements -->
<!-- Native single-line input (no aria-multiline needed) -->
<input type="text" aria-label="Username" />
<!-- Automatically understood as single-line -->
<!-- Native multi-line textarea (no aria-multiline needed) -->
<textarea aria-label="Message" rows="4"></textarea>
<!-- Automatically understood as multi-line -->
<!-- Custom textbox - NEEDS aria-multiline -->
<div
role="textbox"
aria-multiline="true"
aria-label="Bio"
contenteditable="true"
>
<!-- Multi-line content allowed -->
</div>
<!-- Custom searchbox (implicitly single-line) -->
<div
role="searchbox"
aria-label="Search"
contenteditable="true"
>
<!-- Single-line expected (searchbox implies single-line) -->
</div>Rich Text Editor
<!-- Rich Text Editor with aria-multiline -->
<div class="rich-text-editor">
<div role="toolbar" aria-label="Text formatting">
<button aria-label="Bold">B</button>
<button aria-label="Italic">I</button>
<button aria-label="Underline">U</button>
</div>
<div
role="textbox"
aria-multiline="true"
aria-label="Email content"
aria-describedby="editor-instructions"
contenteditable="true"
tabindex="0"
>
<!-- User's text content here -->
</div>
<p id="editor-instructions" class="sr-only">
Press Enter for new paragraph.
Use toolbar buttons for formatting.
</p>
</div>With Combobox
<!-- Combobox with multiline (editable list selection) -->
<!-- Single-line combobox (default) -->
<div
role="combobox"
aria-expanded="false"
aria-haspopup="listbox"
aria-label="Select country"
>
<input type="text" aria-autocomplete="list" />
</div>
<!-- Multi-line combobox (rare, for address entry) -->
<div
role="combobox"
aria-expanded="false"
aria-haspopup="listbox"
aria-multiline="true"
aria-label="Address"
>
<div
role="textbox"
contenteditable="true"
aria-multiline="true"
>
<!-- Multi-line address -->
</div>
</div>React Component
// React Custom Textbox with Multiline Support
import { useState, useRef } from 'react';
function CustomTextbox({
label,
multiline = false,
value,
onChange,
placeholder,
rows = 4,
...props
}) {
const textboxRef = useRef(null);
const handleInput = (e) => {
const content = e.target.textContent || '';
onChange?.(content);
};
const handleKeyDown = (e) => {
// Prevent Enter key in single-line mode
if (!multiline && e.key === 'Enter') {
e.preventDefault();
}
};
return (
<div className="form-field">
<label id={`${props.id}-label`}>
{label}
</label>
<div
ref={textboxRef}
role="textbox"
aria-labelledby={`${props.id}-label`}
aria-multiline={multiline}
aria-placeholder={placeholder}
contentEditable
tabIndex={0}
onInput={handleInput}
onKeyDown={handleKeyDown}
style={{
minHeight: multiline ? `${rows * 1.5}em` : '2em',
whiteSpace: multiline ? 'pre-wrap' : 'nowrap',
overflow: multiline ? 'auto' : 'hidden',
}}
className="custom-textbox"
{...props}
/>
<style>{`
.custom-textbox {
padding: 8px 12px;
border: 1px solid #d1d5db;
border-radius: 6px;
outline: none;
}
.custom-textbox:focus {
border-color: #6366f1;
box-shadow: 0 0 0 2px rgba(99, 102, 241, 0.2);
}
.custom-textbox:empty::before {
content: attr(aria-placeholder);
color: #9ca3af;
}
`}</style>
</div>
);
}
// Usage Examples
function ContactForm() {
const [name, setName] = useState('');
const [message, setMessage] = useState('');
return (
<form>
{/* Single-line input */}
<CustomTextbox
id="name"
label="Your Name"
multiline={false}
value={name}
onChange={setName}
placeholder="Enter your name"
/>
{/* Multi-line input */}
<CustomTextbox
id="message"
label="Your Message"
multiline={true}
rows={6}
value={message}
onChange={setMessage}
placeholder="Type your message here..."
/>
<button type="submit">Send</button>
</form>
);
}Best Practices
Use aria-multiline="true" for custom textarea-like widgets
Enforce Enter key behavior to match the aria-multiline value
Style the element appropriately (taller for multiline, single row for single-line)
Set whitespace CSS to preserve line breaks in multiline fields
Prefer native <textarea> when possible—it handles this automatically
Don't use aria-multiline on native input or textarea elements
Don't set aria-multiline="true" but block Enter key functionality
Don't forget to handle keyboard behavior for single-line inputs
Don't use on elements without role="textbox"

