Ronalds Vilciņš

The HTML Details That Make Forms More Accessible

An accessible form rarely needs ARIA sprinkled over it at the end. It needs controls with names, instructions that remain visible, actionable errors, and a sensible keyboard path.

Most of that starts with ordinary HTML.

Keep the field name visible

A placeholder disappears when someone types:

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

Use a label:

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

Choose the input type that fits the value and include autocomplete where useful:

<input type="email" name="email" autocomplete="email">

That gives browsers enough information for better keyboards, validation, and autofill.

Connect instructions and errors

<label for="password">Password</label>
<input
  id="password"
  type="password"
  aria-describedby="password-help"
>
<p id="password-help">Use at least 12 characters.</p>

An error needs more than a red border:

<label for="email">Email</label>
<input
  id="email"
  type="email"
  aria-describedby="email-error"
  aria-invalid="true"
>
<p id="email-error">Enter a valid email address.</p>

On a long form, focus can move to an error summary or the first invalid field, as long as the user can understand why it moved.

Group controls that answer one question

<fieldset>
  <legend>Preferred contact method</legend>
  <label>
    <input type="radio" name="contact" value="email">
    Email
  </label>
  <label>
    <input type="radio" name="contact" value="phone">
    Phone
  </label>
</fieldset>

<legend> gives the group a shared name.

Make interaction visible and predictable

input:focus-visible,
textarea:focus-visible,
select:focus-visible,
button:focus-visible {
  outline: 3px solid currentColor;
  outline-offset: 3px;
}

Test the entire form using Tab. Do not block paste into passwords, confirmation fields, or one-time codes; password managers and copy-and-paste are useful features.

Use action-specific button text such as “Send message” instead of “Submit”. Mark required or optional fields consistently, and ask only for information the form needs.

Client-side validation helps someone correct the form. Server-side validation still protects the application and data, so use both.

The best form improvement is often removing a field. Start with labelled native controls, make errors actionable, and add ARIA only for relationships HTML cannot express by itself.

Enjoyed reading this?

If you found this article helpful, consider supporting my writing. Every little bit helps keep this blog going.

← Back to all articles