LessonLesson 18 of 34

Accessible forms: instructions, errors, and completion

Design forms people can complete with keyboards, screen readers, speech input, zoom, and clear recovery from errors.

Advanced5 min readLearn · Practice · Review

Published by HTML Code Runner · AI-assisted material · Independent editorial review pending · Editorial policy

On this page

Learning objectives

Distinguish name, description, and error text; make groups understandable; announce completion without disrupting focus.

Prerequisites

Read form foundations, choice controls, and constraint validation. Understand basic ARIA relationships.

A control needs more than a placeholder

A visible label tells a person what a field asks for and usually supplies its accessible name through a native association. Help text explains an additional condition, such as where to find a reference number. An error explains a current problem. These are related but different pieces of information, and compressing all three into a placeholder makes the form fragile.

Use aria-describedby to associate additional help text with a control. Its value can contain multiple IDs, so the description can include both persistent instructions and an error. Keep each referenced ID unique. The visible label should remain a short, stable description of the field rather than changing into a long error sentence.

Design the sequence before the styling

Put controls in the order people are likely to complete them. Keep DOM order aligned with visual order. Native fields, buttons, and links participate in keyboard navigation without positive tabindex values; adding tabindex="5" usually creates a surprising sequence and should be avoided.

Group related choices with fieldset and legend. Separate a shipping address from a billing address with meaningful labels rather than relying only on columns. Large forms may need sections or steps, but every step should explain progress and preserve previous values. Do not impose a short timeout without a real requirement and a way to extend it where possible.

Make target areas generous, allow text to wrap, and test at substantial zoom. A label placed inside a narrow fixed-height row can overlap its control when translated or enlarged. Responsive design is not only about shrinking columns; it must keep the task understandable when less information fits on screen.

Treat feedback as part of the task

After validation, explain which fields need correction. A summary at the top can link to each field, while a nearby message describes the exact issue. Set aria-invalid="true" when reporting a field’s invalid state, and remove or reset it after the problem is resolved. Do not mark every required field invalid before the person has interacted with the form.

Use a status region for a non-urgent result such as Saved on this device. If the workflow moves to a confirmation page, give that page a clear title and heading. Focus should follow the task’s needs: a severe blocking error may justify moving focus to an error summary, while routine background updates usually should not steal focus.

Accessibility cannot be established from markup alone. Test the complete interaction: instructions, entry, invalid submission, correction, successful result, and recovery from a network failure. Native HTML gives a strong starting point but does not automatically make the surrounding workflow usable.

Working example

<label for="member">Membership number</label>
<input id="member" name="member" inputmode="numeric" aria-describedby="member-help">
<p id="member-help">Use the eight digits printed below the barcode.</p>

Another example

<label for="member-error-field">Membership number</label>
<input id="member-error-field" name="member" value="123" aria-invalid="true" aria-describedby="member-format member-error">
<p id="member-format">Enter eight digits.</p>
<p id="member-error">The number has only three digits. Check the number below your barcode.</p>

Expected output

The first field has a stable label and persistent help. The second represents an already-validated error state and exposes both format guidance and a specific correction message. It is an example state, not a complete validation system.

Common mistakes

Do not use aria-label to replace a clear visible label with unrelated wording. Do not announce all help text assertively on page load. Do not move focus on every keystroke or erase correct fields after one field fails.

Accessibility and browser notes

Check accessible names in the browser accessibility tree, then test with real keyboard and screen-reader interaction. Browser and assistive-technology combinations can differ in how descriptions are announced. Keep critical instructions visible and understandable independently of announcements.

Practice

Design a donation amount field with visible currency, a persistent minimum instruction, and an error state for an amount below the minimum.

Review the solution and reasoning
<label for="amount">Donation amount in rupees</label>
<input id="amount" name="amount" type="number" min="50" value="20" aria-invalid="true" aria-describedby="amount-help amount-error">
<p id="amount-help">The minimum amount is 50 rupees.</p>
<p id="amount-error">Enter 50 or more to continue.</p>

The label includes the unit, help states the rule, and the error supplies a direct next action. A real application must validate the amount again on the server and must not treat this demonstration as a payment implementation.

Related lessons

Specifications and further reading

One more skill in your toolkit.

Finished the explanation and exercise? Save your progress.