Designing Accessible Forms: Labels, Errors and Validation Done Right

Accessibility checklist icon for accessible form design

Forms are where most websites ask their users to do something. Sign up, get a quote, make an enquiry, complete a purchase. They are also where accessibility failures hit hardest. A sighted mouse user might breeze through a poorly built form without noticing anything wrong, but a screen reader user, a keyboard-only user or someone with a cognitive disability will run into barriers that make the form partially or entirely unusable. Priority Pixels provides accessibility auditing and remediation services for organisations across the UK. Form accessibility is one of the most frequent issues flagged during audits. The gap between what developers assume works and what assistive technology interprets is often wider than expected.

Getting forms right requires more than dropping a plugin onto a page. It means writing proper HTML, associating labels correctly, communicating errors in ways that every user can perceive and building validation logic that doesn’t create invisible barriers. The good news is that none of this is particularly complicated once you understand the rules. The standards are clear, the patterns are well documented and the fixes are straightforward to implement.

Why Form Accessibility Gets Overlooked

Most form accessibility problems stem from a disconnect between visual design and underlying code structure. A designer places a placeholder inside a text input that reads “Your email address” and assumes the form is labelled. Visually it looks fine. A sighted user reads the placeholder text, fills in their email and moves on. But a screen reader announces the input without any label at all, because placeholder text is not a label. The user hears “edit text, blank” and has no idea what information the field expects.

This is a pattern that repeats across nearly every type of form control. Radio buttons without group labels, select menus with generic prompts like “Choose one”, error messages that appear on screen in red text but aren’t announced to assistive technology, required fields marked only with a visual asterisk. Each of these is a barrier. Each one is also a WCAG failure. The WCAG 2.2 understanding documents specify exactly how form controls should behave under success criteria 1.3.1 (Info and Relationships), 3.3.1 (Error Identification), 3.3.2 (Labels or Instructions) and 4.1.2 (Name, Role, Value). These aren’t aspirational targets. They are the AA conformance requirements that UK public sector bodies are legally bound to meet. Private sector organisations should be meeting them under the Equality Act 2010.

The other common cause is reliance on form builder plugins that generate markup the developer never inspects. WordPress form plugins vary enormously in their accessibility support. Some produce clean, well-labelled HTML. Others output nested div structures with JavaScript-driven validation that bypasses native browser behaviour entirely. If you don’t inspect the rendered HTML your form plugin generates, you’re trusting a third party to get accessibility right on your behalf. That trust is frequently misplaced.

Labels That Work for Everyone

A form label does two things. It tells the user what a field expects. It also programmatically associates that instruction with the input so that assistive technology can announce it. Both parts need to be present. A visible label without a programmatic association is broken for screen reader users. A programmatic association without a visible label is broken for sighted users who rely on text to understand the interface.

The simplest and most reliable way to label a form field is with the HTML <label> element and its for attribute. The for value must match the id of the input it describes. This creates an explicit association that every screen reader recognises.

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

<label for="phone">Phone number (optional)</label>
<input type="tel" id="phone" name="phone" autocomplete="tel">

<label for="message">Your message</label>
<textarea id="message" name="message" rows="5"></textarea>

The code above is readable by every screen reader on the market. When a user focuses the email field, their screen reader announces “Email address, edit text” and they know exactly what to type. The autocomplete attributes are worth noting too. WCAG 2.2 success criterion 1.3.5 (Identify Input Purpose) requires that inputs collecting common personal information declare their purpose programmatically. The autocomplete attribute satisfies this requirement and also lets browsers and password managers pre-fill values, which benefits every user.

Wrapping the input inside the label element (implicit labelling) is another valid approach, but explicit labelling with for and id is more widely supported and more predictable across assistive technologies. Stick with the explicit method unless you have a specific reason not to.

Grouping Related Controls with Fieldset and Legend

Fix icon representing form accessibility remediation techniques

Individual labels handle text inputs and textareas well, but radio buttons and checkboxes need an additional layer of context. Consider a set of radio buttons asking “How did you hear about us?” with options like “Search engine”, “Social media” and “Recommendation”. Each radio button has its own label, but without a group label the screen reader user hears “Search engine, radio button” without knowing what question is being asked. They’re given the answer without the question.

The correct pattern uses <fieldset> to group the controls and <legend> to provide the group label. Most screen readers announce the legend text before each option within the group, so the user hears “How did you hear about us? Search engine, radio button, 1 of 3” which gives them full context.

<fieldset>
  <legend>How did you hear about us?</legend>
  <div>
    <input type="radio" id="source-search" name="source" value="search">
    <label for="source-search">Search engine</label>
  </div>
  <div>
    <input type="radio" id="source-social" name="source" value="social">
    <label for="source-social">Social media</label>
  </div>
  <div>
    <input type="radio" id="source-recommendation" name="source" value="recommendation">
    <label for="source-recommendation">Recommendation</label>
  </div>
</fieldset>

Fieldsets are also useful for grouping sections of longer forms, such as separating billing address fields from delivery address fields. The legend acts as a heading for that group, giving the user orientation within a complex form. Be careful with styling, though. Some CSS resets strip fieldset borders and legend positioning in ways that break the visual grouping, so test your styles with a screen reader to confirm the semantic structure still works as intended.

One thing to avoid is nesting fieldsets more than one level deep. Assistive technology support for deeply nested fieldsets is inconsistent. It tends to create a confusing announcement pattern. Keep groupings flat where possible.

Communicating Errors Clearly

Error handling is where many forms fail their accessibility audit. The visual pattern is familiar: the user submits the form, fields with problems get a red border, a message appears next to each invalid field, sometimes the page scrolls to the first error. For a sighted user this is usually obvious enough. For a screen reader user, none of this may be perceivable unless the developer has taken specific steps to make it so.

WCAG success criterion 3.3.1 (Error Identification) requires that when an input error is automatically detected, the item in error is identified and the error is described to the user in text. Colour alone is not sufficient. A red border without an accompanying text message fails this criterion because colour-blind users may not perceive the change. Screen readers don’t announce colour either. The error message must be in text, it must identify which field has the problem and it should suggest how to fix it.

There are two practical approaches to connecting error messages with their fields. The first is using aria-describedby to associate an error message element with the input. The second is using aria-errormessage, which was designed specifically for this purpose. The aria-describedby approach has broader assistive technology support as of early 2026, so it remains the safer choice for production sites.

<label for="postcode">Postcode</label>
<input type="text" id="postcode" name="postcode"
       aria-describedby="postcode-error" aria-invalid="true"
       autocomplete="postal-code">
<p id="postcode-error" class="error-message" role="alert">
  Enter a valid UK postcode, for example SW1A 1AA
</p>

The aria-invalid="true" attribute tells assistive technology that this field contains an error. The aria-describedby attribute points to the error message, so when the user focuses the field they hear the label followed by the error description. The role="alert" on the error message means it will be announced as soon as it appears in the DOM, even if the user’s focus is elsewhere. This is particularly useful for forms that validate inline as the user moves between fields.

For forms with multiple errors, provide a summary at the top of the form listing every problem. The GOV.UK Design System error summary pattern is an excellent reference for this. Each item in the summary should link to the corresponding field, so keyboard users can jump directly to the problem. Move focus to the error summary when the form is submitted with errors, ensuring screen reader users are immediately aware that something needs correcting.

Required Fields and Instructions

Marking required fields with an asterisk is a convention that most web users understand, but it is not universally understood and it is not sufficient on its own for accessibility. Screen readers may not announce a CSS-generated asterisk. Users with cognitive disabilities may not know what the symbol means. WCAG success criterion 3.3.2 (Labels or Instructions) requires that labels or instructions are provided when content requires user input. For required fields, this means the requirement must be communicated programmatically as well as visually.

The HTML required attribute is the simplest way to mark a field as mandatory. It triggers native browser validation, prevents the form from being submitted with empty required fields and is announced by screen readers as part of the field description. If you want more control over the validation experience, you can use aria-required="true" instead, which communicates the requirement to assistive technology without triggering native browser validation.

Approach Browser Validation Screen Reader Announcement Best Used When
required attribute Yes, blocks submission Announces “required” You want native validation with no custom JavaScript
aria-required="true" No Announces “required” You handle validation in JavaScript with custom error messages
Visual asterisk only No Not announced Never, on its own this fails WCAG 3.3.2

If your form uses asterisks as a visual cue, add a note at the top of the form explaining that fields marked with an asterisk are required. This satisfies 3.3.2 for sighted users. Combine this with the required or aria-required attribute on each field to cover assistive technology users as well. The instructions don’t need to be elaborate. A single line reading “Fields marked with * are required” is enough, placed before the first form field so users see it before they start filling anything in.

For fields that need specific formatting, such as date fields expecting DD/MM/YYYY or phone number fields expecting a UK format, provide the instruction within the label or as hint text associated with the field using aria-describedby. Do not rely on placeholder text for instructions. Placeholder text disappears as soon as the user starts typing, which means the instruction vanishes at precisely the moment the user might need to refer to it.

ARIA Attributes and When to Use Them

Warning icon highlighting common ARIA accessibility pitfalls in forms

ARIA (Accessible Rich Internet Applications) is a set of attributes that extend HTML semantics for assistive technology. In the context of accessible forms, ARIA fills gaps where native HTML falls short. The first rule of ARIA, as stated by the W3C’s own guidance, is not to use it if a native HTML element already does the job. A <label> element is always preferable to aria-label. A <button> element is always preferable to <div role="button">. ARIA is a patch for situations where the correct native element is not available, not a substitute for writing proper HTML.

That said, there are form patterns where ARIA is the right tool. We’ve already covered aria-describedby for error messages and aria-invalid for marking fields in error. Here are the other ARIA attributes most commonly needed in accessible form design.

  • aria-label provides an accessible name when a visible label is not present. Use it sparingly. A search form with a single input and a button labelled “Search” might use aria-label="Search the site" on the input rather than a visible label, but most form fields should have visible labels.
  • aria-describedby associates supplementary information with a control. Use it for hint text, format instructions or error messages. Multiple IDs can be space-separated to point to more than one descriptive element.
  • aria-required="true" marks a field as required without triggering native browser validation. Use it when you handle validation entirely in JavaScript.
  • aria-live regions announce content changes that happen after the page has loaded. Set aria-live="polite" on a container where inline validation messages appear, so the screen reader announces them without interrupting the user’s current action.
  • aria-disabled="true" marks a control as visible but not interactive. Unlike the native disabled attribute, aria-disabled doesn’t remove the element from the tab order, so screen reader users can still reach it and understand why it’s disabled.

The risk with ARIA is overuse. Adding aria-label to every field that already has a visible <label> creates conflicting information. Adding role="form" to a <form> element is redundant. Adding aria-hidden="true" to a visible error message makes it invisible to screen readers. These are real mistakes that appear in production forms regularly. Incorrect ARIA is worse than no ARIA at all, because it actively misleads assistive technology about the page structure.

Validation Patterns That Don’t Create Barriers

Client-side validation improves the user experience by catching errors before the form is submitted to the server. Done well, it saves time and reduces frustration. Done badly, it creates new barriers that are often worse than the problems it was trying to solve.

Native HTML validation is the most accessible starting point. Using input types like email, url and tel together with attributes like required, pattern and maxlength gives you basic validation that works with assistive technology out of the box. Browser-generated error messages are automatically announced to screen readers and are presented in the user’s language. The trade-off is that native validation messages are not very customisable visually, which leads many web design teams to replace them with custom JavaScript validation.

If you choose custom validation, you need to replicate the accessibility behaviour that native validation provides for free. That means programmatically associating error messages with their fields, managing focus when errors appear, using live regions to announce inline errors and ensuring that the error state is communicated through aria-invalid rather than colour alone. You also need to test the validation behaviour with a keyboard and a screen reader, not just with a mouse.

Avoid validating on every keystroke. Real-time character-by-character validation creates a stream of screen reader announcements that is overwhelming and distracting. Validate on blur (when the user leaves the field) or on form submission instead. If you validate on blur, make sure the error message doesn’t shift the page layout in a way that causes other fields to move. Layout shifts during form completion are disorienting for everyone and particularly problematic for users with motor impairments who are targeting specific screen locations.

Server-side validation should always back up client-side checks. Users with JavaScript disabled, older browsers or certain assistive technology configurations may bypass client-side validation entirely. The server should validate every submission independently, return clear error descriptions and ensure the form is re-rendered with all previously entered data intact. Losing a user’s form data on validation failure is a usability failure as much as an accessibility one.

Testing Forms for Accessibility

Automated testing tools will catch some form accessibility problems but miss many others. Tools like WebAIM’s contrast checker can verify that error message text meets colour contrast requirements. Browser extensions like axe DevTools can flag missing labels and empty form controls. These are useful first passes, but they can’t tell you whether a screen reader user can complete your form successfully from start to finish.

Manual testing is where the real issues surface. Tab through the entire form using only a keyboard. Can you reach every field, every button, every interactive control? Can you tell which field has focus at all times? Can you submit the form and understand the error feedback without looking at the screen? If any of those answers is no, you have an accessibility barrier.

Test with at least one screen reader. NVDA with Firefox on Windows is free and widely used. VoiceOver is built into macOS and iOS. JAWS remains the most common screen reader in professional settings. You don’t need to become an expert in each one, but you should be able to navigate a form and listen to how fields, labels and errors are announced. The experience is often revealing. Fields that look perfectly labelled visually might announce as “edit text, blank” in a screen reader because the label association is missing or broken.

The conversion rate optimisation benefits of accessible forms are worth noting too. Forms that are easier to understand, easier to complete and less error-prone convert at higher rates across all user groups, not just those using assistive technology. Clear labels, helpful error messages and logical tab order reduce form abandonment. Accessible form design and good UX design are not separate disciplines. They are the same thing, applied with the awareness that your users interact with your site in different ways.

Common Form Accessibility Failures to Audit For

If you’re reviewing an existing form for accessibility, these are the issues to check first. They represent the most frequent failures found across web development projects of all sizes. Each one maps directly to a WCAG 2.2 success criterion.

  • Inputs without associated labels (fails 1.3.1 and 4.1.2). Every input, select and textarea must have a programmatic label.
  • Placeholder text used as the only label (fails 3.3.2). Placeholder text is not announced consistently by all screen readers and disappears on input.
  • Error messages communicated only by colour (fails 1.4.1 and 3.3.1). Red borders or red text without an accompanying text description is not perceivable by colour-blind users or screen reader users.
  • Error messages not programmatically associated with their fields (fails 3.3.1). An error message sitting visually next to a field but not connected via aria-describedby or equivalent will not be announced when the field receives focus.
  • Radio buttons or checkboxes without a group label (fails 1.3.1). Groups of related controls need a fieldset and legend.
  • Custom dropdowns or date pickers that are not keyboard accessible (fails 2.1.1). If a control cannot be operated using only a keyboard, it fails at the most basic WCAG level.
  • Form submission triggers that are not <button> elements (fails 4.1.2). Using a <div> or <span> styled as a button without proper ARIA roles means keyboard users and screen reader users may not be able to submit the form.
  • Missing autocomplete attributes on personal data fields (fails 1.3.5). Fields collecting names, email addresses, phone numbers and addresses must declare their input purpose.

Running through this list on your existing forms will catch the majority of accessibility issues. For a thorough assessment, pair this checklist with screen reader testing and keyboard-only navigation testing across your most critical user journeys. Contact forms, quote request forms, registration flows and checkout processes should all be tested as complete journeys, not just as isolated components.

FAQs

What are the most common mistakes in accessible forms web design?

The most frequent mistakes include using placeholder text instead of proper labels, missing programmatic associations between labels and inputs, and error messages that appear visually but aren’t announced to screen readers. Many developers also rely on form plugins without checking if they generate accessible HTML markup.

Do I need to use fieldset and legend elements for all form groups?

You should use fieldset and legend for radio button groups and checkbox groups where users need context about what question is being asked. They’re also helpful for grouping related sections in longer forms, like separating billing and delivery address fields.

How should I handle error messages so screen reader users can understand them?

Error messages must be connected to their fields using aria-describedby and the field should have aria-invalid=”true” when there’s an error. Add role=”alert” to error messages so they’re announced immediately when they appear, and provide an error summary at the top of forms with multiple problems.

Is marking required fields with an asterisk enough for accessibility?

An asterisk alone isn’t sufficient because screen readers may not announce CSS-generated symbols and some users don’t understand what it means. You need to add the required attribute or aria-required=”true” to communicate the requirement programmatically to assistive technology.

When should I use ARIA attributes instead of standard HTML elements?

Only use ARIA when native HTML elements can’t do the job – standard HTML should always be your first choice. ARIA is most useful in forms for aria-describedby (linking hint text or errors), aria-invalid (marking fields with errors), and aria-required (when you don’t want native browser validation).

Avatar for Monica Johnson Monica Johnson
Senior Designer at Priority Pixels

Monica designs websites and digital assets that are clear, functional and built around user experience. She works across web and graphic design, using Figma, Adobe XD, Illustrator and Photoshop to bring creative ideas to life. Her focus is always on design that supports performance and reflects each client’s identity.

Related Insights

Practical advice on B2B digital marketing, from lead generation and brand strategy to campaign performance.

What is the best cache plugin for WordPress in 2026
B2B Marketing Agency
Have a project in mind?

Every project starts with a conversation. Ready to have yours?

Start your project
Web Design Agency