Form Labels and Error Messaging

Form controls need explicit, programmatically determinable labels, and validation errors need accessible feedback that identifies the affected field and explains how to correct it. Good implementations make the relationship between the control, its label, its error, and its current validity available to assistive technology.

A form control should have a label that identifies its purpose. In HTML, the most reliable pattern is a `<label>` associated with an `<input>` through matching `for` and `id` values; wrapping a control inside a `<label>` is another valid pattern. Placeholder text is not a substitute for a label because it can disappear when the user enters a value and is generally less reliable as an accessible name.

When validation fails, the user needs to know which field is invalid and what needs to change. The error should be associated with the relevant control, commonly with `aria-describedby`, while the control's invalid state can be exposed with `aria-invalid="true"`. The message should describe the problem rather than merely saying that the input is invalid.

Client-side validation should not rely solely on visual styling such as a red border or an icon. The error text needs to be available to users who cannot perceive those visual cues. If errors are added dynamically, consider whether the update also needs to be announced, for example with an appropriate live region or by moving focus to a useful location after submission.

A useful structure is: label the control, preserve the label when an error appears, expose the invalid state, connect the error text to the control, and give the user a concrete correction. For grouped controls such as radio buttons or checkboxes, use an appropriate group label such as `<fieldset>` and `<legend>` when the controls share one question or purpose.

Key points

Interview questions

Why should a form input have a `<label>` instead of only a placeholder?

A label identifies the purpose of the control and remains available after the user enters a value. A placeholder is temporary hint text and is not a good replacement for the control's label. An explicit `<label for>` and matching `id` creates a programmatic relationship that assistive technologies can use. It also gives users a larger clickable label area in common browser behavior.

How would you make a validation error accessible?

I would identify the invalid field with a useful error message and expose its state with `aria-invalid="true"`. I would associate the error text with the control using `aria-describedby`. The message should explain the problem and, where practical, how to correct it. I would not depend on color or an icon alone to communicate the error.

What is the difference between `aria-label` and `aria-describedby`?

`aria-label` provides an accessible name for an element, whereas `aria-describedby` points to additional descriptive content. For a normal form field with visible text, I would generally prefer a real `<label>` for the name. I might use `aria-describedby` to connect help text or an error message to that field. The two attributes therefore solve different parts of the accessibility relationship.

Should every invalid input have `aria-invalid="true"` from the beginning?

Usually, the invalid state should reflect the application's actual validation state rather than marking every field invalid before the user has interacted with it or submitted the form. After validation determines that a value is invalid, `aria-invalid="true"` can communicate that state to assistive technology. The exact timing depends on the validation UX. The important principle is that the ARIA state should match the actual state presented by the interface.

What should happen when a user submits a form containing several errors?

The form should make the errors discoverable and clearly associate each message with its corresponding control. A common pattern is to provide a summary of the errors and move focus to the summary or another useful starting point, while also exposing field-level errors. Each invalid control should retain its label and have a specific description of the problem. The interaction should avoid unexpectedly moving focus around while the user is correcting fields.