Code Reference

Accessible Form

Html · Example / how-to

Accessible Form

Html · Example / how-to


📋 Overview

Build a contact form with proper labels, error association, required fields, and keyboard-friendly controls.

🔧 Core concepts

PieceRole
<label for>Name the control
aria-describedbyLink help / errors
aria-invalidMark failed fields
Native typesemail, required

💡 Examples

<form action="/contact" method="post" novalidate>
  <fieldset>
    <legend>Contact us</legend>

    <div>
      <label for="email">Email</label>
      <input
        id="email"
        name="email"
        type="email"
        autocomplete="email"
        required
        aria-describedby="email-hint email-error"
        aria-invalid="true"
      />
      <p id="email-hint">We never share your email.</p>
      <p id="email-error" role="alert">Enter a valid email address.</p>
    </div>

    <div>
      <label for="message">Message</label>
      <textarea
        id="message"
        name="message"
        rows="5"
        required
        aria-describedby="message-hint"
      ></textarea>
      <p id="message-hint">Max 1000 characters.</p>
    </div>

    <div>
      <input id="consent" name="consent" type="checkbox" required />
      <label for="consent">I agree to the privacy policy</label>
    </div>
  </fieldset>

  <button type="submit">Send</button>
</form>

Clear error state when valid (JS sketch):

input.setAttribute("aria-invalid", "false");
error.textContent = "";

⚠️ Pitfalls

  • Placeholder is not a label — screen readers and recall suffer.
  • Only using color for errors fails contrast / color-blind users.
  • novalidate disables native checks — pair with your own accessible errors.

On this page