All fix guides
WarningAccessibility

Fix Form Inputs Missing Labels (Accessibility)

Your audit found form controls (inputs, textareas, selects) with no programmatically associated label. Screen readers announce these as unnamed, so users don't know what to type, and machines parsing the form can't tell what each field is for. Fix it by giving every control an accessible name: a real label tied by for/id, a label that wraps the control, or an aria-label / aria-labelledby attribute.

What this means

This warning (audit codes input_missing_label and input_no_label_or_aria) means the crawler found one or more form controls (<input>, <textarea>, or <select>) that have no accessible name. A placeholder is not a label. Neither is nearby text that only looks associated visually. For a control to count as labeled, the browser's accessibility tree must be able to compute a name for it through one of these:

  • A <label> whose for attribute matches the control's id.
  • A <label> that wraps the control directly.
  • An aria-label attribute on the control.
  • An aria-labelledby attribute pointing to the id of visible text.
  • A title attribute (weakest; a last resort, not a primary name).

If none of these exist, the field is unlabeled. The most common cause is a search box or newsletter field that relies only on placeholder="Search...". Placeholder text disappears once the user starts typing, is often too low-contrast to read, and is not reliably exposed as the accessible name by assistive tech. Hidden inputs (type="hidden"), buttons, and submit/reset controls don't need labels and are normally excluded by good checkers, so if one of those is flagged, verify the finding.

Why it matters

The direct impact is accessibility. A screen reader user who tabs into an unlabeled field hears "edit text, blank" with no clue what to enter. That fails WCAG 2.x Success Criteria 1.3.1 (Info and Relationships), 3.3.2 (Labels or Instructions), and 4.1.2 (Name, Role, Value), the criteria most often cited in accessibility complaints. Labels help everyone: clicking a proper label focuses its field and enlarges the tap target, which matters on mobile.

Accessibility is not a documented Google ranking factor, but missing labels still cost you. They fail Lighthouse's Accessibility audit and show up in PageSpeed Insights. On lead-gen and checkout pages, a form that screen readers and autofill can't parse loses conversions from a slice of your traffic. Browser autofill leans on label text and autocomplete values to fill fields correctly, so unlabeled controls autofill poorly.

For answer engines, the label is the field's machine-readable name. When ChatGPT's browsing tool, Perplexity, or Google's AI systems read a page, the accessible name is how they identify what each control does. As AI agents move toward completing forms on a user's behalf, a form of named fields is one an agent can act on, while a form of anonymous boxes is opaque. Accessible-name coverage is the same substrate that serves screen readers, Googlebot, and AI crawlers.

How to fix it

  1. 1

    Add a real label tied by for/id

    The canonical fix: give the control a unique id and point a <label for="..."> at it. It works everywhere, needs no ARIA, and makes the visible text clickable to focus the field. Example: <label for="email">Email address</label><input id="email" type="email" name="email">. Every id must be unique on the page; duplicate ids break the association silently.

  2. 2

    Or wrap the input inside the label

    When you can't add matching id/for pairs, for instance in a component that generates ids you don't control, nest the control inside the label: <label>Email address <input type="email" name="email"></label>. The association is implicit, so no for or id is required. This is often the cleanest option in JSX and React component libraries.

  3. 3

    Use aria-label or aria-labelledby when no visible label fits

    For controls with no visible text label, such as a search box or a filter dropdown, add aria-label="Search products" directly to the control. If descriptive text already exists elsewhere on the page, reference its id with aria-labelledby instead of duplicating the string. Do not use placeholder as the name; keep it as a hint and add the real label separately.

  4. 4

    Add autocomplete and the right type while you're in the markup

    Since you're editing each field, set the correct autocomplete token (email, name, tel, street-address, and so on). This improves browser autofill and satisfies WCAG 2.1 SC 1.3.5 (Identify Input Purpose) for fields that collect user information. Pair it with the right input type (email, tel, url, number) so mobile keyboards and validation behave correctly.

  5. 5

    Fix it at the template level for repeated forms

    Most unlabeled fields come from one template, theme, or plugin rendering the same form site-wide, so fixing the source clears many findings at once. Contact forms, header search widgets, and newsletter blocks are the usual culprits. See the platform steps below for WordPress form plugins, Shopify, Wix, and Squarespace.

  6. 6

    Re-scan and verify in the accessibility tree

    Re-run this audit and confirm the count drops to zero. Then check in Chrome DevTools: open the Elements panel, select the input, and open the Accessibility pane. The Name field should show your label text and its source. Lighthouse's 'Form elements do not have associated labels' audit should also pass.

Example

<!-- 1. Best: explicit label via for/id (visible, clickable) -->
<label for="user-email">Email address</label>
<input id="user-email" type="email" name="email"
       autocomplete="email" required>

<!-- 2. Implicit label: wrap the input (no id needed) -->
<label>
  Full name
  <input type="text" name="name" autocomplete="name">
</label>

<!-- 3. No visible label (e.g. search box): visually-hidden real label -->
<form role="search">
  <label for="q" class="sr-only">Search</label>
  <input id="q" type="search" name="q" placeholder="Search...">
  <button type="submit">Go</button>
</form>

<!-- WRONG: placeholder is not a label -->
<input type="email" placeholder="Email address">

<!-- CSS for the visually-hidden pattern (keeps it in the a11y tree) -->
<style>
.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;
}
</style>

Three valid ways to label a control, the wrong way, and a visually-hidden label.

Platform-specific steps

Raw HTML / Next.js / React

In plain HTML, add for/id pairs or wrap inputs in <label>. In React and JSX, use htmlFor instead of for: <label htmlFor="email">Email</label><input id="email" />. Generate stable unique ids with React's useId() hook so they don't collide across component instances. For icon-only or search inputs with no visible text, add aria-label. If you use a form library (React Hook Form, Formik), confirm each registered field renders an associated label; the library won't add one for you.

WordPress (Contact Form 7, WPForms, Gravity Forms)

Yoast and RankMath are SEO plugins and won't touch form labels; this lives in your form plugin and theme. In Contact Form 7, wrap each tag in a label: <label>Your email [email* your-email]</label>. WPForms and Gravity Forms add labels automatically but may have 'Hide Label' enabled per field. Turn that off, or set the field's screen-reader label in its Advanced settings. The most-flagged field is usually the theme's header search widget; edit the search form template or block to add a <label> for the search input.

Shopify

Unlabeled fields usually come from theme Liquid: the header search, footer newsletter, and login/register forms. Edit the relevant sections and snippets (for example search-form.liquid or the newsletter section) and add a <label> with a visually-hidden class or an aria-label to each <input>. Dawn-based themes are mostly labeled already; older or heavily customized themes are where gaps appear. Also check any forms injected by third-party apps.

Wix

Wix's standard form and search elements include accessible names, but custom forms built with older tools or embedded through an HTML/iframe widget often don't. For native fields, open each field's settings and set the field title rather than relying only on placeholder text. For anything you injected through an Embed or Custom Element, edit that HTML directly to add <label> or aria-label.

Squarespace

Squarespace's Form and Newsletter blocks render labels from each field's Title, so make sure every field has a Title filled in rather than only placeholder text. If a Title is set but hidden by design, leave it populated so the label still exists in markup. For custom forms added through a Code Block, add the <label> or aria-label markup yourself.

Free tool
Check this with the UI/UX Checker

Frequently asked

Does a placeholder count as a label?

No. A placeholder is a hint, not an accessible name. It vanishes as soon as the user types, is often too low-contrast to read, and isn't reliably exposed to assistive technology as the field's name. Lighthouse still flags inputs that have only a placeholder. Keep the placeholder if you want, but add a real label or aria-label in addition.

Can I hide the label visually but keep it for screen readers?

Yes, and it's the recommended pattern for a bare search box. Keep a real <label> in the markup and move it off-screen with a visually-hidden / sr-only CSS utility that clips it to a 1px box. Never use display:none or visibility:hidden, which remove it from the accessibility tree. The label stays available to screen readers and to machines while being invisible on screen. An aria-label on the control achieves the same result with less markup.

Do search boxes and newsletter fields really need labels?

Yes. Every interactive form control needs an accessible name, including single-field search and email-signup forms. They're the most commonly flagged fields precisely because designers strip the visible label. Use a visually-hidden <label> or an aria-label such as aria-label="Search" or aria-label="Email address".

Which is better: label for, aria-label, or aria-labelledby?

Prefer a visible <label> associated by for/id or by wrapping. It helps sighted users, enlarges the click target, and needs no ARIA. Use aria-labelledby when correct descriptive text already exists on the page and you want to reuse it. Use aria-label only when there's genuinely no visible text to point at. The first rule of ARIA applies: use native HTML when you can.

Will fixing form labels improve my Google rankings?

Not directly; accessibility is not a documented ranking factor. But labeled forms raise your Lighthouse and PageSpeed accessibility scores, improve autofill and completion on conversion-critical forms, and reduce legal exposure. They also make forms parseable by AI crawlers and agents. The payoff is better user outcomes and cleaner semantic HTML, which search and AI systems reward indirectly.

Does your site have this issue?

Run a free, AI-powered audit and we’ll flag this and 150+ other checks in about a minute. No signup.

No signup needed. Results in under 60 seconds.

Related fixes