Form summary 1.2.2
The <velin-form-summary> Web Component turns native constraint validation into an accessible error summary: one focusable panel listing every invalid field, with aria-invalid and aria-describedby wired up per field. Deutsch: Formular Zusammenfassung
When to use
- Multi-field forms where users must see all errors after submit (WCAG 3.3.1 Error Identification).
- You want actionable messages next to fields and in a linked summary (WCAG 3.3.3 Error Suggestion).
- Prefer native constraint validation (
required,type,pattern, …) over a custom validation engine.
When not
- Do not use it as a substitute for server-side validation or TLS.
- Do not rely on browser bubbles alone for complex forms — that is what this component replaces.
- Skip it for single-field widgets where an inline
.velin-field-erroris enough; still pair CSS states from Validation.
Why not native validation?
The browser's own validation bubble shows one error at a time, disappears on its own, cannot be styled, and is inconsistently exposed to assistive technology. On a form with several problems the user has to discover them one submit at a time.
This component sets novalidate on the form and takes over: on submit it collects every invalid field, renders a persistent summary, and moves focus there. Constraint validation itself is unchanged — required, type, pattern, min, maxlength and custom messages all still apply.
Basic
Place the element inside the form, or anywhere on the page with for pointing at the form id.
<form id="signup">
<velin-form-summary heading="There is a problem with your details"></velin-form-summary>
<label class="velin-form-label" for="email">Email address</label>
<input class="velin-form-control" id="email" name="email" type="email" required>
<button type="submit" class="velin-btn velin-btn--primary">Create account</button>
</form>
Submitting with errors renders a role="alert" panel, focuses it, and announces the number of fields needing attention. Each summary entry links to its field; activating one moves focus straight to the input. Errors clear per field as soon as that field becomes valid, so the summary shrinks as the user works through it — it never re-flags a field the user has not submitted yet.
Custom messages and containers
By default the browser's validationMessage is used, which is already localised. Override it per field, and control how the field is named in the summary:
<input id="name" name="name" required
data-error-message="Enter your full name"
data-error-label="Name">
Messages are injected as a .velin-field-error element after the field and referenced from aria-describedby. To control placement, supply your own container — the component fills it instead of creating one, and leaves it in the DOM when the error clears:
<input id="email" name="email" type="email" required>
<p class="velin-field-error" data-velin-error-for="email"></p>
Existing aria-describedby hints are preserved: the error id is appended, so a field can point at both its hint and its error.
Attributes
| Attribute | Default | Notes |
|---|---|---|
for | — | Form id; omit when nested inside the form |
heading | There is a problem | Summary heading text |
native-validation | — | Keeps the browser's own bubbles (does not set novalidate) |
Per-field attributes: data-error-message, data-error-label, data-error-ignore (skip the field entirely), and data-velin-error-for on a message container. Disabled fields are always skipped, and a radio group is listed once rather than per radio.
JavaScript API
const summary = document.querySelector('velin-form-summary');
summary.validate(); // returns true when the form is valid
summary.focusFirstError(); // move focus to the first invalid field
summary.clear(); // drop the summary and all field error state
summary.errors; // [{ field, label, message }]
summary.form; // the bound form element
Events
velin-form-invalid— submit blocked;detail.errorslists label and message per fieldvelin-form-valid— the last outstanding error clearedvelin-form-error-focus— a summary link moved focus;detail.nameidentifies the field
Accessibility
- WCAG 3.3.1 Error Identification: invalid fields get
aria-invalid, a visible.velin-field-error, and an entry in the focusablerole="alert"summary list. - WCAG 3.3.3 Error Suggestion: messages come from the browser
validationMessageordata-error-messageso users know how to fix the problem. aria-describedbyis maintained automatically (4.1.2 Name, Role, Value); existing hint ids are preserved.- Summary entries are links to real field ids; activating one moves focus to the field (
velin-form-error-focus). - The error count is announced assertively through
<velin-announcer>(4.1.3 Status Messages). - Errors appear only after an explicit submit, not while the user is typing a field for the first time.
Contract status in core/a11y/component-contracts.json: pass.
Related
- Forms — Validation (CSS valid/invalid states)
- Persist (redundant entry / draft values)
- Announcer
- A11y patterns