DEV Community

cadguide.tools
cadguide.tools

Posted on Originally published at a11ykit.site

How to Build 100% Accessible Forms: Labels, Focus Traps, and Error States

Forms are the lifeblood of the web — they are where signups, checkouts, and customer interactions happen. Yet forms remain the single biggest source of digital accessibility barriers.

According to web accessibility audits, over 58% of form inputs on top websites lack valid programmatic labels.

Here is how to build completely accessible forms that pass WCAG 2.2 Level AA while looking modern and sleek.


🏷️ 1. Explicit Labels Are Mandatory

Never rely on placeholder text as a label. Placeholders vanish upon typing, have low contrast by default, and are not consistently voiced by screen readers.

<!-- ❌ WRONG -->
<input type="email" placeholder="Enter your email" />

<!-- ✅ RIGHT: Explicit association via id and for -->
<label for="user-email" class="form-label">Email address</label>
<input id="user-email" type="email" name="email" required />
Enter fullscreen mode Exit fullscreen mode

🚨 2. Accessible Error States & Validation

When a user submits invalid data:

  1. Don't rely on color alone (a red border is invisible to users with red-green color blindness).
  2. Announce errors programmatically using aria-invalid and aria-describedby:
<label for="password-input">Password</label>
<input
  id="password-input"
  type="password"
  aria-invalid="true"
  aria-describedby="password-error-msg"
/>
<p id="password-error-msg" class="error-text" role="alert">
  ⚠️ Password must be at least 8 characters long.
</p>
Enter fullscreen mode Exit fullscreen mode

🎯 3. Grouping Related Inputs with Fieldset & Legend

For radio button groups or multi-checkbox questions, group them with <fieldset> so screen readers announce the group context before each individual choice:

<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>
Enter fullscreen mode Exit fullscreen mode

🛠️ Instant Form Audit Tool

Want to verify whether your current website has missing labels, broken for/id associations, or unlabelled inputs?

👉 Scan your forms with the A11yKit Form Label Checker

What's the biggest headache your team encounters when styling accessible forms? Share your tips below!

Top comments (0)