reala11y GUIDES Accessible formsin WordPress:labels, errors… Nov 16, 2021

November 16, 2021 · reala11y team

Accessible forms in WordPress: labels, errors, instructions

Build accessible WordPress forms: visible labels, programmatic association, clear errors and instructions. A practical, honest guide to WCAG 3.3.2 and 3.3.1.

Forms are where accessibility quietly breaks. A site can have clean headings, good contrast, and useful alt text, then hand a screen-reader user a checkout form whose fields announce as “edit text, blank.” The user has no idea what to type. They abandon the form, and you never see why.

Two WCAG 2.2 success criteria govern most of this: 3.3.2 Labels or Instructions (every input needs a clear label or instruction) and 3.3.1 Error Identification (when input fails, say what went wrong, in text). Both are Level A. Both are very common, and both are fixable in code.

Visible labels, not placeholders

The single most frequent form mistake is using placeholder text as the label:

<input type="email" placeholder="Email address">

Placeholders vanish the moment someone starts typing, fail contrast requirements in most themes, and are not reliably announced by assistive technology. Once the field has a value, the user has no on-screen reminder of what it holds.

Use a real, visible <label> instead:

<label for="email">Email address</label>
<input type="email" id="email" name="email">

A placeholder can still offer a format hint (“[email protected]”), but it is never a substitute for the label.

Program the association, don’t just place it nearby

Sighted users connect a label to a field by proximity. Assistive technology needs the connection in the markup. There are two reliable ways:

When a control genuinely can’t take a visible label (an icon-only search button, say), aria-label or aria-labelledby carries the accessible name. Prefer a visible label whenever the layout allows it; a label everyone can see helps users with cognitive and motor differences too, not only screen-reader users.

This is one of the spots where WordPress itself trips up. Plugin-generated search widgets, comment forms, and contact forms often emit an input with no associated label at all. The fix is small and structural, which is exactly the kind of issue reala11y identifies and remediates at the code level — by correcting the underlying HTML, not by layering a widget over it.

Instructions belong before the input

If a field has rules — a password length, a required format, an accepted file type — say so before the user reaches it, not only after they get it wrong.

<label for="pwd">Password</label>
<p id="pwd-hint">At least 12 characters, including one number.</p>
<input type="password" id="pwd" aria-describedby="pwd-hint">

aria-describedby ties the hint to the field so it’s announced along with the label. Mark required fields in text or with a programmatically exposed required attribute — never with colour or an unexplained asterisk alone.

Errors a person can actually act on

WCAG 3.3.1 asks that when an entry is rejected, the error is identified in text and the user is told which field failed and why. That rules out the patterns everyone has suffered:

A solid error pattern does three things:

Move focus to the first invalid field, or to a summary at the top of the form that links to each error. That keeps keyboard and screen-reader users oriented instead of lost.

Test it the way real users do

Automated scanning catches a meaningful share of form problems — missing labels, empty buttons, mismatched for/id — but it can’t judge whether your label text is meaningful or your error message is useful. So pair the two:

For the full criteria — including what changed in WCAG 2.2 (a W3C Recommendation since 5 October 2023) — see our WCAG 2.2 guide.

The honest takeaway

Accessible forms are mostly unglamorous code hygiene: a real label, a matching id, a hint in the right place, an error message that says what to fix. None of it requires an overlay or a magic button. Automated tools, including reala11y, typically surface 30–40% of WCAG issues by criteria and help your site move toward WCAG 2.2 AA conformance — the remaining judgment calls still need a human at the keyboard. Fix the markup, then go listen to your own form. That last step is where the real bugs show up.