Limits of CKEditor 5 inline validation announcement for screen readers in Drupal 10.x
0 reputation · 20 Dec 2021, 12:38 UTC
0 reputation · 20 Dec 2021, 12:38 UTC
When using Drupal’s CKEditor 5 inline editor, form validation messages (e.g., required‑field warnings) appear visually but are not automatically exposed to screen‑reader users via an ARIA live region.
The goal is to determine whether the core should add a polite live region to announce these errors, and if so, what markup and placement would satisfy accessibility guidelines without interfering with existing visual styling or custom overrides.
Uncertainties remain about the optimal container role, the timing of the announcement relative to the visual alert, and how to handle cases where themes or modules already provide their own live regions.
aria-live="polite" element alongside each inline validation message, or rely on a single global live region for all editor errors?role="alert") best convey the error while preserving the polite behavior?35275 reputation · 20 Dec 2021, 18:03 UTC
Drupal core should rely on the existing global status‑messages live region rather than injecting a per‑editor aria-live="polite" element. The error message should be associated with the editor wrapper using aria-describedby (or aria-errormessage) so that screen readers announce it in context without needing a new live region per instance.
.messages.error outside the editor element and already uses a polite live region for status messages.contenteditable div; error messages are sibling nodes without programmatic association, so screen readers do not automatically announce them in the editor’s context.Because the error markup is inserted as a sibling to the editor, screen readers only perceive it when they encounter it in the DOM order. Without an explicit association (aria-describedby) or a live region that references the editor, the error is not announced in relation to the field, leading to missed or de‑contextualized feedback.
id (e.g., ckeditor-inline-{{ field_name }}).aria-describedby="{{ wrapper_id }}" (or aria-errormessage) to the error message element.div.messages--status[aria-live="polite"]) unchanged; it will automatically announce the updated error text.once() to attach the aria-describedby attribute only once per editor instance, preventing duplication if themes or modules also modify the markup.aria-live ancestor before adding attributes.Does the page already contain a Drupal status‑messages region with aria-live="polite"? If not, the recommendation changes to injecting a single global polite live region (e.g., div[role="status"][aria-live="polite"]) before relying on aria-describedby association.
Use comments to ask for clarification. Post a solution as an answer.
35,275 reputation · 20 Dec 2021, 14:31 UTC
Adding aria-live to an element that lives inside the contenteditable wrapper can trigger announcements on every keystroke, which is disruptive for screen‑reader users. The CKEditor 5 UI is isolated from Drupal’s form API, so the error message should live outside the editor’s editable area.
<div class="field-wrapper" id="field-wrapper-1" aria-describedby="error-1">
<div class="ck-editor__editable" contenteditable="true">…</div>
<div id="error-1" class="form-error" role="alert">This field is required.</div>
</div>
div as a sibling of the editor wrapper, not inside the contenteditable.
role="alert" for urgent validation errors; screen readers will announce it immediately.
div with aria-live="polite" if you want a non‑interruptive update.
aria-describedby="error-1" so assistive technology can navigate directly.
Before injecting a new live region, check for an existing role="alert" or aria-live region in the page. If one is present, append the new error message to that region instead of creating a second one.
Testing tip: after a failed validation, inspect the DOM to confirm the error element is a sibling of the editor wrapper and that focus moves to the first error. Use a screen reader to ensure the message is announced once and not repeated.