All components

Contact form with accessible validation

A compact form for contacts or enquiries: explicit labels, errors wired to their fields, client-side validation, a submit state and a final message inside an announceable region.

Form demo

Simulated submission: try empty fields, an invalid email and a message that is too short.

Validation Errors Status

Project enquiry

Collect useful data without leaving the user guessing.

Every error has its own text and stays tied to its field through aria-describedby.

Component notes

When to use it

For contacts, quotes, short sign-ups or any flow where field-level feedback genuinely matters.

What it solves

It avoids generic errors and invisible states: every field says clearly what is missing and what is valid.

How to adapt it

Wire the submit to your own API or a form service. The demo keeps markup, styling and validation separate.

A guide to building accessible contact forms with real-time validation

Contact forms are the main communication channel between users and a web application. Badly designed or inaccessible validation is one of the leading causes of user frustration, and often leads people to abandon the form entirely. A correct implementation therefore has to combine client-side validation (for immediate feedback) with robust HTML that respects the accessibility guidelines (WCAG).

This form uses explicit labels through the <label> tag, tied directly to their input fields via the for attribute. That guarantees that clicking the label moves focus to the text field, and that screen readers read the field's name correctly as the user navigates to it. Real-time validation checks format correctness (for email, say) or minimum text length as the user types or when the field loses focus (the blur event).

Error handling is the most critical part: when a field is invalid, the aria-invalid attribute is set to true and the ID of the specific error message is linked to the field through aria-describedby. That way a screen reader user hears the error immediately on moving to the affected field. Finally, the submit state and the final success message go inside a container with role="status" or aria-live="polite", so the outcome is announced to the user without reloading the page or forcibly moving focus.

Quick FAQ about validated forms

How are error messages linked to input fields?

Through the aria-describedby attribute on the input, whose value matches the ID of the paragraph holding the error. This creates a semantic link that screen readers announce automatically when the input receives focus.

Do you still need server-side validation if client-side validation is in place?

Yes. Client-side validation exists to improve the user experience with immediate feedback, but it is trivially bypassed (by disabling JavaScript or sending direct HTTP requests). Server-side validation is always mandatory for security and data integrity.

Can I customize the browser's native error messages?

Yes — by turning off native validation with the novalidate attribute on the <form> tag and handling custom messages in JavaScript, as this component does. That keeps you in full control of both the visual design and the tone of voice of your errors.