Learn
02.3 | VALIDATION AND ACCESSIBLE FORMS
01 | CHECK THE INPUT, HELP THE PERSON
A student tries to book a robotics workshop. They miss the email field and enter 12 participants for a session with six places. The form needs to explain what to change, without deleting the rest of their work.
Validation checks whether input meets stated rules. It can identify a missing required value, an invalid format or a number outside a range. It cannot prove that every plausible value is true.
Accessible forms make labels, instructions, controls and errors understandable and usable, including with a keyboard or assistive technology. Clear requirements prevent errors; clear feedback helps people recover.
02 | START WITH NATIVE HTML CONSTRAINTS
<label for="email">Email address (required)</label>
<input type="email" id="email" name="email" required>
<label for="participants">Participants (1 to 6, required)</label>
<input type="number" id="participants" name="participants"
min="1" max="6" step="1" required>required prevents supported controls from being left empty. type="email" checks basic email syntax. min and max constrain a numeric value; step="1" specifies whole-number steps here, starting from the minimum.
Optional email fields may remain empty. Add required when a value is compulsory. An email-shaped value can still be invented or mistyped, so syntax checking does not establish that an address exists.
Native browser messages and control appearance vary. Browser validation normally runs before a standard form submission. It does not implement the server’s checks.
03 | LENGTH AND PATTERN RULES
<label for="team-code">Team code (required)</label>
<p id="team-code-hint">Use two capital letters followed by three digits,
for example AB123.</p>
<input type="text" id="team-code" name="team_code"
pattern="[A-Z]{2}[0-9]{3}" required
aria-describedby="team-code-hint">
<label for="project-title">Project title (required, 5 to 40 characters)</label>
<input type="text" id="project-title" name="project_title"
minlength="5" maxlength="40" required>pattern uses a regular expression to constrain supported text-like inputs. [A-Z]{2} means two capital letters, and [0-9]{3} means three digits. HTML pattern checking matches the complete value in this example.
minlength and maxlength set text length limits. They are not numeric minimum and maximum values. Use min and max for quantities.
Give users visible instructions before they enter data. Do not hide the only explanation in a tooltip or a placeholder. Apply rules because the data needs them, not simply because the attributes exist.
04 | CONNECT HINTS TO CONTROLS
<label for="idea">Project idea (required)</label>
<p id="idea-hint">In a sentence or two, explain what your robot will do.</p>
<textarea id="idea" name="idea" rows="4" required
aria-describedby="idea-hint"></textarea>The label gives the control its name. aria-describedby points to additional explanatory text using its id. It supports the label rather than replacing it.
When several pieces of text describe a control, list their ids separated by spaces, such as aria-describedby="idea-hint idea-error".
Use plain language for compulsory fields and accepted formats. If an asterisk means “required”, explain it. Writing “required” in the label is often clearer.
05 | MAKE ERRORS SPECIFIC AND CONNECTED
<label for="contact">Email address (required)</label>
<p id="contact-hint">Use an address in the form name@example.com.</p>
<input type="email" id="contact" name="email" required
aria-invalid="true"
aria-describedby="contact-hint contact-error">
<p id="contact-error">Enter an email address in the form name@example.com.</p>This example shows an error state after a failed validation attempt. Do not mark a fresh, untouched form invalid simply because its required fields are still empty.
aria-invalid="true" communicates that the input has been judged invalid. It does not perform validation, block submission or create an error message. Code must manage that state when using custom feedback.
A useful message identifies the field and explains the correction. “Participants must be a whole number from 1 to 6” is more helpful than “Invalid”. Use text alongside visual styling so colour is not the only cue.
06 | KEEP KEYBOARD NAVIGATION PREDICTABLE
Use native inputs, selects and buttons. Put them in a logical source order and keep visible focus indicators. Labels should activate their controls, and related radio choices should have a fieldset and legend.
After an unsuccessful submission, a custom form can provide an error summary and links to the affected controls. Moving focus to that summary can help users discover the problems. Preserve valid entries so they do not need to start again.
A short status message may use role="status" for polite announcements without moving focus. Avoid announcing every keystroke or sending the same message through several announcement mechanisms.
Test with Tab, Shift+Tab and the expected native keys. A successful mouse test alone does not show that a form is accessible.
07 | BROWSER CHECKS AND SERVER CHECKS
Client-side validation happens in the browser and provides quick feedback. Server-side validation happens where a real submission is processed and must enforce the application’s rules.
Users can modify HTML, disable scripts or send requests directly. Therefore the server must validate even when the browser has already checked the values.
Validation is also different from verification. Checking that a team code has the form AB123 does not prove that the team exists. A server lookup may be needed for that. Validation alone does not make an application secure.
For a beginner form, start with clear labels and native constraints. Custom error handling adds responsibilities, so introduce it only when you can preserve accessible behaviour.
08 | TRY IT: FIND AND FIX THE ERRORS
Leave a field blank, use a malformed email address or try a team code such as abc12. Submit, follow an error-summary link and correct the entry. Your other values stay in place.
This demo uses JavaScript to inspect the native constraint states and show custom messages. It checks the fields again on each submit. Error messages remain until you check again, making the feedback predictable.
Nothing is sent or saved. Passing these checks means the entries meet this demo’s rules; it does not create a booking or verify that the email address and team exist.