Accessibility Fix Guide

How to Fix Missing Form Labels for WCAG and ADA Accessibility

Forms are one of the most common places accessibility breaks on a website. A visitor may be able to read your homepage, navigate your menu, and understand your offer, but if they cannot complete your contact form, checkout form, login form, booking form, or newsletter signup, the website still fails at one of its most important jobs. One of the simplest and most frequent form accessibility problems is the missing form label.

A missing label happens when an input, select menu, checkbox, radio button, or textarea does not have a clear programmatic name that tells assistive technology what the control is for. Visually, the page might look fine. A designer may have placed placeholder text inside the field, or the form may rely on surrounding layout to make the purpose obvious. But for a screen reader user, voice-control user, keyboard user, or someone using browser autofill, the form control may be announced as something vague like "edit text," "combo box," or "checkbox not checked" with no useful context.

That creates a real barrier. Users may not know whether they are supposed to enter an email address, phone number, password, coupon code, ZIP code, or message. In checkout flows and account forms, missing labels can prevent people from completing the transaction entirely.

This page is informational and is not legal advice. Accessibility requirements can vary by site, organization, and jurisdiction. For legal guidance, consult qualified counsel. For accessibility conformance, combine automated scans with manual testing.

What is a missing form label?

A form label is the text that identifies a form control. For example:

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

In this example, the visible text "Email address" is connected to the input through the for and id attributes. When a screen reader reaches the input, it can announce the field as "Email address, edit text" instead of just "edit text." A missing form label occurs when the control does not have an accessible name.

Example of a problematic input:

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

This may look labeled to a sighted user because the placeholder says "Email address," but placeholder text is not a reliable replacement for a real label. It disappears when the user starts typing, may have low contrast, and can be inconsistently announced depending on the browser and assistive technology.

A better version:

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

This version is clearer, more durable, and easier for assistive technology to understand.

Why missing labels matter

Missing form labels affect multiple groups of users. For screen reader users, the label tells them what the field is asking for. Without it, a screen reader may announce only the control type. A user might hear "edit text" without knowing what to enter.

For voice-control users, labels help identify controls by name. A user may say "click Email address" or "select State." If the field has no accessible name, voice navigation can become harder or impossible. For people with cognitive disabilities, visible labels help reduce memory load. Placeholder-only forms force users to remember what the field was asking after they begin typing.

For keyboard users, labels improve predictability. When a user tabs through fields, each field should have a stable, visible description. For everyone, labels improve usability. Clear labels make forms easier to scan, easier to complete, and less likely to produce errors.

WCAG criteria related to form labels

WCAG 1.3.1 — Info and Relationships

This criterion is about preserving relationships that are visually implied. If a label appears visually next to a field, that relationship should also be available programmatically. A screen reader should be able to determine that "Email address" belongs to the email input.

WCAG 3.3.2 — Labels or Instructions

This criterion focuses on helping users understand what input is expected. Labels, instructions, examples, and format hints help users complete forms correctly.

WCAG 4.1.2 — Name, Role, Value

Interactive components need a programmatically determinable name, role, and value. A form input with no accessible name can create a failure here because assistive technology may not be able to communicate what the control is.

The most common bad patterns

Placeholder-only labels

This is one of the most common issues.

<input type="text" placeholder="Full name">
<input type="email" placeholder="Email">
<input type="tel" placeholder="Phone">

This looks minimal and clean, but it is not the best accessible pattern. The label disappears once the user types, and placeholder text is often styled with low contrast.

Better:

<label for="full-name">Full name</label>
<input id="full-name" name="fullName" type="text" autocomplete="name">

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

<label for="phone">Phone</label>
<input id="phone" name="phone" type="tel" autocomplete="tel">

You can still include placeholder text if it adds an example, but the placeholder should not be the only label.

<label for="phone">Phone number</label>
<input
  id="phone"
  name="phone"
  type="tel"
  autocomplete="tel"
  placeholder="Example: 555-123-4567"
>

Floating labels implemented incorrectly

Floating labels can be accessible if implemented carefully. The problem happens when the visual label is just a styled placeholder or is not programmatically connected to the field.

Problem:

<div class="floating-field">
  <input type="email" placeholder="Email address">
</div>

Better:

<div class="floating-field">
  <input id="email" name="email" type="email" autocomplete="email">
  <label for="email">Email address</label>
</div>

The visual design can still float the label with CSS. The important part is that the label element exists and is associated with the input.

Icon-only fields

Search boxes are often implemented with only a search icon.

Problem:

<form>
  <input type="search" name="q">
  <button type="submit">
    <svg aria-hidden="true">...</svg>
  </button>
</form>

Better:

<form role="search">
  <label for="site-search" class="sr-only">Search this site</label>
  <input id="site-search" name="q" type="search" autocomplete="off">

  <button type="submit" aria-label="Submit search">
    <svg aria-hidden="true" focusable="false">...</svg>
  </button>
</form>

Here, the input has a hidden but accessible label, and the icon-only button has an aria-label.

Unlabeled checkboxes

Checkboxes need labels too.

Problem:

<input type="checkbox" name="terms">
<span>I agree to the Terms of Service</span>

The text is visually near the checkbox, but it is not programmatically associated.

Better:

<label>
  <input type="checkbox" name="terms">
  I agree to the Terms of Service
</label>

Or:

<input id="terms" type="checkbox" name="terms">
<label for="terms">I agree to the Terms of Service</label>

The second approach is often easier to style, but both can be valid.

Radio groups without fieldsets

Radio buttons usually need both individual labels and a group label.

Problem:

<p>Preferred contact method</p>

<input type="radio" name="contact" value="email"> Email
<input type="radio" name="contact" value="phone"> Phone
<input type="radio" name="contact" value="text"> Text

Better:

<fieldset>
  <legend>Preferred contact method</legend>

  <input id="contact-email" type="radio" name="contact" value="email">
  <label for="contact-email">Email</label>

  <input id="contact-phone" type="radio" name="contact" value="phone">
  <label for="contact-phone">Phone</label>

  <input id="contact-text" type="radio" name="contact" value="text">
  <label for="contact-text">Text message</label>
</fieldset>

The legend explains the purpose of the group. Each radio button also has its own label.

When can you use aria-label?

A real visible label is usually better than aria-label. Visible labels help everyone, not only assistive technology users. That said, aria-label can be appropriate when a visible label would be redundant or when the purpose is already visually clear through context.

Example:

<button aria-label="Close modal">
  <svg aria-hidden="true" focusable="false">...</svg>
</button>

For form fields, use aria-label sparingly. Acceptable in some cases:

<input type="search" name="q" aria-label="Search products">

Usually better:

<label for="product-search" class="sr-only">Search products</label>
<input id="product-search" type="search" name="q">

A visually hidden label gives you a real label element while keeping the design minimal. Example utility class:

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

How to fix missing labels step by step

Step 1: Find every form control

Look for:

<input>
<select>
<textarea>
<button>

Buttons need accessible names too, especially icon-only buttons.

Step 2: Check whether each control has a clear name

For most fields, look for a connected label:

<label for="company">Company</label>
<input id="company" name="company" type="text">

The for value must match the input's id.

Incorrect:

<label for="company-name">Company</label>
<input id="company" name="company" type="text">

Correct:

<label for="company">Company</label>
<input id="company" name="company" type="text">

Step 3: Replace placeholder-only labels

Before:

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

After:

<label for="email">Email</label>
<input id="email" name="email" type="email" placeholder="you@example.com">

Step 4: Add labels to checkboxes and radio buttons

Before:

<input type="checkbox" id="newsletter">
<span>Send me updates</span>

After:

<input type="checkbox" id="newsletter" name="newsletter">
<label for="newsletter">Send me updates</label>

Step 5: Use fieldsets for grouped options

Before:

<p>Plan type</p>
<label><input type="radio" name="plan"> Starter</label>
<label><input type="radio" name="plan"> Pro</label>

After:

<fieldset>
  <legend>Plan type</legend>

  <label>
    <input type="radio" name="plan" value="starter">
    Starter
  </label>

  <label>
    <input type="radio" name="plan" value="pro">
    Pro
  </label>
</fieldset>

Step 6: Connect help text and error text

Labels tell users what the field is. Help text and error text provide extra guidance.

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

For an error:

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

Do not replace the label with the error message. The user still needs the field label.

How ADA CodeFix detects missing labels

ADA CodeFix scans pages for form controls that appear to be missing accessible names. It looks for common issues such as:

The scanner can help identify issues quickly, but automated tools cannot verify every accessibility problem. For example, a field might technically have an accessible name, but the name could still be vague, misleading, or incomplete. That is why developer review and manual testing are still important.

Manual testing checklist

Use this checklist after making changes.

  1. Can every input be identified without relying on placeholder text?
  2. Does every label for value match the correct input id?
  3. Do checkboxes and radio buttons have clear labels?
  4. Do radio groups have a fieldset and legend when appropriate?
  5. Do icon-only buttons have accessible names?
  6. Are help messages connected with aria-describedby?
  7. Are error messages connected with aria-describedby?
  8. Does the label remain visible after the user starts typing?
  9. Can the form be completed using only the keyboard?
  10. Does a screen reader announce the field name and purpose clearly?

A quick screen reader test can catch issues that code review misses. Tab through the form and listen for whether each field is announced with a meaningful name.

Common mistakes to avoid

Mistake 1: Using only placeholder text

Placeholder text is not a substitute for a label. It disappears, may have poor contrast, and is not as reliable as a connected label.

Mistake 2: Hiding labels with display: none

Do not hide a label like this:

label {
  display: none;
}

Elements hidden with display: none are generally removed from the accessibility tree. If you need a visually hidden label, use a proper screen-reader-only CSS pattern.

Mistake 3: Reusing the same id

This is invalid and can break label associations.

Problem:

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

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

Better:

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

<label for="confirm-email">Confirm email</label>
<input id="confirm-email" type="email">

Mistake 4: Label text that is too vague

A label like "Name" may be fine in some forms, but sometimes "Full name," "First name," or "Cardholder name" is clearer.

Vague:

<label for="name">Name</label>
<input id="name" name="name" type="text">

Clearer:

<label for="billing-name">Name on card</label>
<input id="billing-name" name="billingName" type="text" autocomplete="cc-name">

Mistake 5: Adding ARIA when native HTML would be better

ARIA can help, but native HTML labels are usually simpler and more reliable. Avoid overcomplicating this:

<div role="textbox" aria-label="Email address" contenteditable="true"></div>

Prefer:

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

Platform-specific notes

WordPress

Many WordPress form plugins generate labels automatically, but some themes hide them for design reasons. Check contact forms, newsletter forms, search forms, checkout forms, and comment forms. If labels are visually hidden, confirm they remain available to assistive technology.

Shopify

Review product option selectors, cart forms, discount-code inputs, checkout-adjacent forms, newsletter popups, and search fields. Shopify themes sometimes use placeholder-only newsletter forms or icon-only search buttons.

Webflow

Webflow makes it easy to visually design forms, but custom styling can separate labels from inputs. Confirm each field has a label element and that the label is connected to the correct input.

React and Next.js

When building reusable components, make sure the component accepts and applies a stable id.

function TextField({ id, label, type = "text", ...props }) {
  return (
    <div className="field">
      <label htmlFor={id}>{label}</label>
      <input id={id} type={type} {...props} />
    </div>
  );
}

Avoid generating labels visually without connecting them to inputs.

Final takeaway

Missing form labels are one of the easiest accessibility issues to overlook because the form may look complete visually. But accessibility is not only about what appears on screen. It is also about whether the structure and relationships in the interface are available to assistive technology.

The best fix is usually simple: use a real label, connect it to the correct form control, keep the label visible when possible, and use aria-describedby for extra instructions or error messages. Avoid relying on placeholder text alone. Use ARIA only when native HTML is not enough. ADA CodeFix can help identify missing labels and generate developer-reviewable fixes, but a human should still review the form, test it with a keyboard, and confirm that each field is understandable in context.

Sources

Run a free WCAG 2.1 AA scan on your site

ADA CodeFix scans your pages, identifies likely WCAG failures, and generates developer-reviewable code fixes for labels, focus styles, alt text, color contrast, and more.

Scan My Site Free