We’re moving to a new home! Our website is currently in test mode while we update and transfer our content. Some pages and resources may be temporarily unavailable. We’ll be back with all resources shortly. Thank you for your patience.

HTML & CSS | 02.3 Validation and Accessible Forms

Lesson objective

Use native constraints to check form input. Connect hints and errors to controls, support keyboard users and explain why browser validation must be backed by server checks.

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.

Use fictional details, for example alex@example.com.

Enter a whole number from 1 to 6.

Two capital letters followed by three digits, for example AB123.

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.

MATCH THE REQUIREMENT

Choose the attribute for each purpose.

Terminology

Terminology

Validation

Checking whether input meets stated rules.

Verification

Checking whether information matches a trusted source or the intended value.

required

An attribute requiring a value in a supported control.

min and max

Attributes setting lower and upper limits for numeric or other supported values.

step

An attribute defining permitted increments for supported input types.

minlength and maxlength

Attributes defining text length limits.

pattern

A regular expression constraining a supported text-like input.

aria-describedby

An attribute referring to ids of text that describes a control.

aria-invalid

An attribute communicating that an input has been judged invalid.

Error summary

An overview of errors, often linking to the affected fields.

Client-side validation

Input checks performed in the browser.

Server-side validation

Input checks performed by the server processing a real request.

Questions

Questions

CHECK YOUR UNDERSTANDING

Select all correct choices. Each exact set earns one point.

1. Which rules suit a compulsory participant count of 1 to 6?
2. What can type="email" establish?
3. Which feedback is helpful?
4. What does aria-describedby do?
5. Which statements about aria-invalid are correct?
6. Why must a server validate submitted data?
7. Which help keyboard users?
8. Which statements are correct?

EXPLAIN AND IMPROVE

Answer in your book before revealing each sample.

1. Write a labelled required number input for a whole-number team size from 2 to 5.

2. Rewrite “Invalid input” as a useful message for a team code that must be two capital letters and three digits.

3. Explain why a placeholder is not enough to communicate a required format.

4. Explain validation and verification using a team code.

5. Describe how an error summary can help someone using a keyboard.

6. Explain why browser validation cannot replace server validation.

BUILD | IMPROVE YOUR CLUB FORM

Update the form you built in 02.2. Add clear required-field wording, a participant range and a visible team-code hint. Use native validation first; test it using fictional values.

Test cases: for a range of 1 to 6, try 0, 1, 6, 7 and 2.5. For the code pattern, try AB123, ab123 and AB12. Record the expected and observed results.

Extension: plan an error summary with field links. Custom handling needs JavaScript and should be tested with assistive technology as well as a keyboard.

Flashcards

Flashcards

Click to flip. Select the ideas you need to revisit.

0 cards selected for revision.

    Selections are kept while this page is open.

    Workbook

    Workbook

    COMING SOON

    The workbook for 02.3 Validation and Accessible Forms is coming soon. Complete the accessible-form task and keep your HTML file for the next lessons.