Advanced

Forms that work without a mouse

Forms are where accessibility failures concentrate, because a form is the one place a page demands information the user must type correctly. Every part of that demand has an accessible shape: a label, a name, a focus order, and an error that says what went wrong.

What you will see

The field is reachable and the error is heard. If the error only appears visually, the link is missing.

About 1 min of reading

Try It

Wire one field end to end

1

Write the pair

printf '\n\n' | tee -a form.html

Before you run it, say out loud what it will print. Then open the answer.

What it prints
A label associated by id, and an input that carries the same id.
2

Add the error link

printf '\n

Email is required and must contain @

\n' | tee -a form.html

Before you run it, say out loud what it will print. Then open the answer.

What it prints
The error is announced when the field is reached, not only when the form is submitted.
3

Check for orphans

grep -oE 'for="[^"]+"' form.html | sed 's/for="//;s/"//' | while read i; do grep -c "id=\"$i\"" form.html; done

Before you run it, say out loud what it will print. Then open the answer.

What it prints
Every label target resolves to 1. A 0 is a label that announces nothing.
4

Type it with no mouse

open form.html, Tab to the input, type, press Enter

Before you run it, say out loud what it will print. Then open the answer.

What it prints
The field is reachable and the error is heard. If the error only appears visually, the link is missing.
Do not clear a field's value and re-render it on error. That deletes what the user typed before they can read the message.

Data Flow

Field to an announced error
1 Label associated by for and id
↓
2 Input focusable in document order
↓
3 Submit runs validation
↓
4 Error linked by aria-describedby and announced at the field
Why this works
The four form checks

Every input has a programmatic label; the tab order matches the visual order; a validation error is announced at the field; and nothing depends on color to say 'required'.

Where placeholder hurts

Placeholder text is announced as part of the name in some technology, so a placeholder of 'your email here' can become the field's name. Keep labels explicit and placeholders minimal.

Examples

Label by association, not proximity

<label for="email"> plus id="email" on the input. The association is what announces the field's name. A label that merely sits above the input announces nothing.

Placeholder text is not a label

Gray placeholder text is not read as a name and is often below the contrast threshold. Put the real requirement in the label, and use placeholder only for an example value.

Errors name the field and the fix

'Email is required' beats 'Invalid input'. The message must be associated with the field via aria-describedby so the reader hears it at the field, not at the bottom of the page.

Words this lesson uses

Each one is defined here on this site. Open the entry for the full definition and the other words it points at.

← Tables that announce their structure
Previous Lesson
Tables that announce their structure
Next Lesson
Custom controls and ARIA, honestly
Custom controls and ARIA, honestly →