Probeo
probeo

Fix Missing Form Labels, Conflicting Labels, and Required Attributes (WCAG 1.3.1)

Form inputs without labels leave assistive technology unable to identify what a field expects. Multiple labels on a single input create ambiguity. Missing required attributes suppress validation cues. This page covers the three most common form accessibility failures and how to resolve them.

Form controls depend on programmatic label associations to be usable by assistive technology. Three failure patterns recur across most codebases: inputs with no label at all, inputs with multiple conflicting labels, and required fields that lack the HTML5 required attribute or aria-required. Each creates a different kind of breakdown. Missing labels leave screen reader users unable to identify what a field expects. Multiple labels cause assistive technology to announce one label while sighted users may see another — the mismatch is silent. Missing required attributes suppress native validation and prevent screen readers from communicating that a field is mandatory before submission fails. WCAG 1.3.1 (Info and Relationships) requires that relationships between labels and controls be programmatically determinable.

What's wrong

One or more form controls lack a programmatic label association. This means the input has no label element whose for attribute matches the input's id, is not wrapped inside a label element, and has no aria-labelledby or aria-label attribute. Without any of these mechanisms, assistive technology announces the input by its type alone — "edit text," "checkbox," "combobox" — with no indication of what it controls. Separately, some inputs have multiple label elements associated with a single control. The HTML specification permits this, but screen reader behavior is inconsistent: some announce the first label, some concatenate both, some announce only the last. The result is an unpredictable experience where the label a sighted user reads may differ from what a screen reader user hears. A third pattern involves required fields that rely on visual indicators (asterisks, colored borders, placeholder text saying "required") without the HTML5 required attribute or aria-required="true". Screen readers cannot detect visual-only cues. Users navigating by keyboard submit the form, receive validation errors, and must locate which fields failed without prior indication that the fields were mandatory.

Why it matters

Forms are transactional. They collect credentials, process payments, capture registrations, and accept search queries. A form that cannot be completed by assistive technology users is not a minor degradation — it is a functional barrier. Missing labels affect every screen reader user who encounters the form. The problem is not that users cannot find the input; it is that they cannot determine what the input expects. A login form with two unlabeled text fields and an unlabeled checkbox is three guesses. Multiple labels create a subtler failure. Developers often add a visible label and a tooltip, or a label and an aria-labelledby, producing two competing names. Assistive technology resolves this according to the accessible name computation algorithm, which follows a specific precedence order. The result may not match what the developer intended, and it is rarely tested. Required attributes affect form completion flow. When a screen reader user tabs through a form, the required attribute causes the reader to announce "required" for each mandatory field. Without it, users have no advance signal. They submit, encounter errors, and must re-navigate the form to find failures — a process that is significantly more costly with assistive technology than with a mouse.

The correct change

Every form control that accepts user input must have exactly one unambiguous programmatic label. The preferred mechanism is a label element with a for attribute matching the input's id. This approach is the most widely supported across assistive technology and provides the largest click target because activating the label focuses the input. When wrapping the input inside the label element, the for/id pairing is unnecessary but the label text must be adjacent and unambiguous. For cases where a visible label is not appropriate (search inputs with a visible button, icon-only controls), use aria-label to provide the accessible name directly, or aria-labelledby to reference visible text elsewhere on the page. Remove duplicate label associations. If an input has both a label element and an aria-labelledby, the aria-labelledby takes precedence and the label element's text is ignored by assistive technology — though sighted users still see it. Choose one mechanism and ensure it is the correct one. Do not combine label, aria-label, and aria-labelledby on the same input. Add the required attribute to every input that must be filled before submission. This provides both native browser validation and an accessible announcement. If the form uses custom validation that suppresses native validation (via novalidate), add aria-required="true" to ensure screen readers still communicate the requirement. Both attributes can coexist without conflict.

Scope

This condition applies at the page level. Every form on the page must be evaluated independently. Label requirements apply to all interactive form elements: input, select, textarea, and custom controls built with role attributes. The scope includes dynamically rendered forms — client-side frameworks that inject form controls after page load must ensure labels are present when the controls become interactive, not deferred to a later render cycle. Component libraries and design systems should enforce label requirements at the component API level, making it impossible to render a form control without a label prop. This prevents the violation at the source rather than catching it in production.

How to verify

  • Validation confirms the condition is resolved:
  • • Every input, select, and textarea has exactly one programmatic label (for/id, wrapping label, aria-label, or aria-labelledby)
  • • No form control has multiple competing label mechanisms that produce different accessible names
  • • Required fields include the required attribute or aria-required="true"
  • • Screen reader testing confirms each field announces its label and required state correctly
  • • Placeholder text is not the sole label for any input — a programmatic label exists independently
  • • Dynamically rendered form controls have labels present when they become interactive
  • • Automated accessibility tools report no label or form-field-multiple-labels violations

Takeaway

  • Every form control needs exactly one unambiguous programmatic label — no fewer, no more
  • The for/id pattern is the most reliable and widely supported label association mechanism
  • Multiple labels on one input produce inconsistent screen reader behavior — remove the duplicate
  • The required attribute serves both native validation and accessibility announcement
  • Placeholder text disappears on input and is not a label replacement
  • aria-labelledby overrides label elements in the accessible name computation — do not combine them unintentionally

FAQ

Can placeholder text serve as a form label?
No. Placeholder text disappears the moment a user begins typing, removing the only identification of what the field expects. Users who look away and return to a partially filled form cannot verify whether they entered data in the correct field. Screen readers may announce placeholder text as a fallback, but support is inconsistent and the behavior differs from a proper label announcement. Placeholder text is supplementary — it can show format hints (MM/DD/YYYY) or examples, but the field's identity must come from a label element, aria-label, or aria-labelledby that persists regardless of input state.
When should visually hidden labels be used instead of visible labels?
Visually hidden labels apply when the field's purpose is unambiguous from visual context but requires a programmatic name for assistive technology. A search input adjacent to a button labeled "Search" is a common case — sighted users understand the field's purpose from the button, but screen reader users need the input to announce "Search" independently. Use CSS to hide the label visually (position: absolute, clip, or the sr-only utility class) while keeping it in the DOM for assistive technology. Do not use display: none or visibility: hidden — both remove the label from the accessibility tree.
How should fieldset and legend be used with related form controls?
Fieldset groups related controls under a shared label provided by the legend element. Radio buttons and checkbox groups are the primary use case — without a fieldset, each radio button announces its own label but not the question it answers. A group of radio buttons labeled "Yes" and "No" is meaningless without the fieldset legend "Do you agree to the terms?" which provides the group context. Screen readers announce the legend when a user enters the fieldset, then announce individual labels within it. Fieldset/legend is not required for every group of fields, but any group where individual labels are ambiguous without shared context needs it.
What happens when a single input has both a label element and aria-labelledby?
The accessible name computation algorithm specifies a precedence order. aria-labelledby takes highest precedence for the accessible name. If an input has a label element with text "Email address" and an aria-labelledby pointing to a span containing "Your email," screen readers announce "Your email" and ignore the label element's text entirely. Sighted users still see "Email address" as the visible label. This mismatch violates WCAG 2.5.3 (Label in Name), which requires the visible label text to be contained within the accessible name. The fix is to use one mechanism, not both.
How does the required attribute differ from aria-required?
The HTML5 required attribute provides both native browser validation (the form will not submit if the field is empty) and an accessibility announcement. aria-required="true" provides only the accessibility announcement — it tells screen readers the field is required but does not trigger native validation. Use required when native validation is appropriate. Use aria-required when the form handles validation in JavaScript (with novalidate on the form element) and native validation is suppressed. Both attributes cause screen readers to announce "required" when the field receives focus. They can coexist without conflict, but having both is redundant if native validation is active.
How should custom form controls (dropdowns, date pickers) handle label associations?
Custom controls built with div, span, or other non-form elements do not inherit native label behavior. They require explicit ARIA roles (role="combobox", role="listbox") and accessible names via aria-label or aria-labelledby. A custom dropdown must have role="combobox" and an aria-labelledby pointing to visible label text or an aria-label providing the name directly. The label element's for attribute only works with native form elements — it has no effect on a div with a role attribute. Custom date pickers need aria-label on the trigger control and aria-live regions or role="status" to announce selected values. Test custom controls with screen readers specifically, because automated tools often miss label failures on non-native elements.