Screen readers do not announce changes in contenteditable regions
OS: macOS Ubuntu 22.04 · Device: Desktop or Laptop Any · Browser: Safari 120.0
Open case →Scenario
Ensuring contenteditable editors are navigable for assistive technology users through proper ARIA mapping and engine synchronization.
Contenteditable regions often present “Accessibility Walls.” While basic typing works, complex features like placeholders, nested blocks, and mention widgets are frequently opaque to screen readers if not paired with a strict ARIA-aware architecture.
Native contenteditable provides no placeholder attribute. Faking it with CSS or empty ::before elements often hides the editor’s existence from screen readers, or announces the placeholder text even after the user starts typing.
Modern browsers build an internal “Accessibility Tree” from the DOM. Rapid mutations (like syntax highlighting or spellcheck decorations) can cause the AX-Tree to refresh too frequently, leading to repetitive or stuttering feedback in tools like NVDA or VoiceOver.
Setting aria-readonly="false" on a role="textbox" element can sometimes override the browser’s native editable detection in Chromium, causing screen readers to incorrectly announce the field as read-only.
When spellcheck="true" is enabled, Safari’s localized suggestion menu can block text selection. Furthermore, red “error squiggles” can persist even after contenteditable is set to false, confusing assistive tools about the document’s interactive state.
Always use role="textbox" and aria-multiline="true" on non-div editors to ensure the correct OS-level handles are created.
Use the ::spelling-error pseudo-element to style errors without polluting the DOM with additional markup. This prevents AX-Tree thrashing from redundant spans.
Visual view of how this scenario connects to its concrete cases and environments. Nodes can be dragged and clicked.
Each row is a concrete case for this scenario, with a dedicated document and playground.
| Case | OS | Device | Browser | Keyboard | Status |
|---|---|---|---|---|---|
| ce-0015-screen-reader-announcements | macOS Ubuntu 22.04 | Desktop or Laptop Any | Safari 120.0 | US | draft |
| ce-0041-spellcheck-interferes | macOS Ubuntu 22.04 | Desktop or Laptop Any | Safari 120.0 | US | draft |
| ce-0054-contenteditable-with-aria | macOS Ubuntu 22.04 | Desktop or Laptop Any | Safari 120.0 | US | draft |
| ce-0573 | macOS 15.0 | Desktop Any | Chrome 129.0 | US QWERTY | confirmed |
| ce-0574 | Windows 11 | Desktop Any | Chrome 124.0 | US QWERTY | confirmed |
This matrix shows which browser and OS combinations have documented cases for this scenario. Click on a cell to view the specific case.
This scenario affects multiple languages. Cases are grouped by language/input method below.
OS: macOS Ubuntu 22.04 · Device: Desktop or Laptop Any · Browser: Safari 120.0
Open case →OS: macOS Ubuntu 22.04 · Device: Desktop or Laptop Any · Browser: Safari 120.0
Open case →OS: macOS Ubuntu 22.04 · Device: Desktop or Laptop Any · Browser: Safari 120.0
Open case →OS: macOS 15.0 · Device: Desktop Any · Browser: Chrome 129.0
Open case →OS: Windows 11 · Device: Desktop Any · Browser: Chrome 124.0
Open case →Other scenarios that share similar tags or category.
Keyboard navigation in contenteditable elements must comply with WCAG 2.1.1 (Keyboard) and 2.1.2 (No Keyboard Trap) requirements. The Tab key typically moves focus out of contenteditable, while arrow keys move the caret. Custom keyboard handling must ensure all functionality is keyboard-operable and focus remains visible.
The `lang` attribute on a contenteditable region does not affect the spellcheck language in Safari. Spellcheck always uses the browser's default language, regardless of the `lang` attribute value.
Have questions, suggestions, or want to share your experience? Join the discussion below.