Website problems

Form inputs without labels

Every form control needs a programmatically associated label — text that assistive technology can read as the name of that field. Without one, a screen reader announces an unnamed edit box and the user has to guess what to type. A visible placeholder does not satisfy this: placeholders disappear as soon as the field has content, are not reliably announced, and routinely fail colour contrast. WCAG 2.2 requires labels or instructions for user input at Level A.

Why a placeholder is not a label

It vanishes. The moment someone types, the only description of the field is gone — which matters most to the people most likely to need it, including anyone who was interrupted mid-form.

It is announced inconsistently. Support varies by browser and screen reader, and it is not a substitute for an accessible name.

It usually fails contrast. Placeholder text is conventionally light grey, which puts it below the 4.5:1 minimum for normal text.

It cannot be clicked. A real `<label>` extends the click target of the control, which matters on touch screens and for anyone with limited fine motor control.

MDN's guidance is direct on this point: do not use the placeholder attribute in place of a label.

The four ways to give a control a name

`<label for="id">` referencing the control's `id`. The standard mechanism, visible on screen, clickable, and universally supported. This is the default choice.

Wrapping: `<label>Email <input type="email"></label>`. Equivalent, and useful where the markup makes an `id` inconvenient.

`aria-labelledby="id"` pointing at existing visible text. Correct when the label already exists elsewhere on the page and duplicating it would be worse.

`aria-label="Search"` as a string. The last resort, because it names the control for assistive technology and leaves sighted users with nothing — acceptable for an icon-only search field, rarely elsewhere.

What does not work: a `<span>` next to the input, a `title` attribute, or text that merely sits nearby. Proximity on screen is not association in markup.

The related failures in the same forms

Error messages that are announced only by colour, or not announced at all. WCAG requires that an input error be identified and described in text.

An error summary that appears without moving focus, so a screen-reader user submits a form and hears nothing change.

Required fields marked only with a red asterisk and no `required` attribute, so the requirement is visual and nothing else.

Missing `autocomplete` attributes. WCAG 2.1 added a criterion requiring the purpose of common input fields to be identifiable programmatically, which is what `autocomplete="email"` or `autocomplete="street-address"` does — and it also makes the form faster for everyone.

Grouped controls without a `<fieldset>` and `<legend>`, so a set of radio buttons announces each option with no statement of what is being chosen.

How to check it yourself

In the console: `[...document.querySelectorAll('input,select,textarea')].filter(el => !el.labels?.length && !el.getAttribute('aria-label') && !el.getAttribute('aria-labelledby'))` returns the controls with no name at all.

Better, use the browser's accessibility pane and read the computed accessible name of each control. That is what a screen reader will announce, and it accounts for all four mechanisms.

Tab through the form with the screen reader on. A field that announces only 'edit, blank' is the defect, heard rather than inferred.

Check hidden and conditional fields too — a step that appears only after a choice is made is a step no static review opens.

How to fix it

Add a visible `<label for>` to every control. This fixes the accessible name, the click target and the contrast problem in one change.

Keep the placeholder for an example of the expected format, not for the field's name. `dd/mm/yyyy` is a good placeholder; `Date of birth` is a label.

Add `autocomplete` values from the HTML specification's list for name, email, address, telephone and payment fields.

Associate error messages with their control using `aria-describedby`, and make the message text describe what to do rather than that something is wrong.

Group related controls in a `<fieldset>` with a `<legend>`, so the question is announced along with the options.

How VeriFixScan detects it

`accessibility.form_errors` examines the forms on each crawled page and reports controls with no programmatically associated label, along with the element and the page it appears on.

`accessibility.autocomplete` reports the common input fields that carry no `autocomplete` value, which is the criterion added in WCAG 2.1 and the one most often absent.

`accessibility.interactive_elements` covers the adjacent case of controls that are not form fields — buttons and links with no accessible name.

What the checks establish is that a name exists. Whether it is a good name is a review, and a field labelled `Field 1` passes the machine test and fails the reader.

Frequently asked questions

Can I use a placeholder instead of a label?
No. It disappears when the field has content, is announced inconsistently by screen readers, usually fails contrast, and is not clickable. MDN's guidance states plainly that it should not replace a label.
Is aria-label as good as a visible label?
For assistive technology, yes. For sighted users it provides nothing, so it fits an icon-only control and rarely anything else. A visible label serves everyone.
Do I need autocomplete attributes?
WCAG 2.1 Success Criterion 1.3.5 requires the purpose of common input fields to be programmatically determinable, which is what autocomplete provides. It also makes forms measurably faster to complete.

Sources

Related

VeriFixScan crawls a site and applies its checks to every page it reaches, keeping the evidence behind each finding. Scanning one website is free.

Scan a website